第四章 变量、作用域和内存问题
基本类型和引用类型
5种基本类型(按值访问):Undefined,Null,Number,String,Boolean
引用类型值:保存在内存中的对象,操作的是对象的引用而不是实际的对象(值会同时发生改变),引用类型的值可以为其添加属性和方法
函数的参数都是按值传递的
检测类型
typeof
instanceof: 什么类型的对象
perseon instanceof Object 是object吗
colors instanceof Array 是array吗
pattern instanceof RegExp
执行环境
全局执行环境(最外围)– window对象 —— 所有变量和函数都是作为window对象的属性和方法创建的!
execution context 执行环境(定义了变量或函数有权访问的其他数据) –> 关联的变量对象 variable object(环境中定义的所有变量和函数) –> 作用域链 scope chian 保证变量和函数的有序访问,前端是缓动对象,arguments对象,之后是包含环境,直到全局环境
执行环境所有代码执行完毕后,该环境被销毁,变量对象也销毁。windiw在关闭页面的时候销毁
没有块级作用域
js的i变量,在循环结束后,仍旧存在于循环外部的执行环境中
垃圾收集
浏览器中的实现通常有两个策略
1. 标记清除 mark and sweep
变量声明时,标记为“进入环境”,离开时标记为“离开环境”
垃圾收集器去在运行时会给存储在内存中所有变量都加上标记,然后去掉环境中的变量以及被环境中的变量引用的变量的标记,在此之后再被加上标记的变量将被视为准备删除的变量。最后垃圾收集器完成内存清除工作,销毁那些带标记的值并回收他们所占用的内存空间。
2. 引用计数(不太常见)reference counting
跟踪每个值被引用的次数。。。不推荐。
但是IE中还存在。循环引用发生时会出现问题
循环引用会导致资源不被回收, 使用完后使用null断开原生
var element = document.getElementById("some_element");
var myObject = new Object();
myObject.element = element;
element.someObject = myObject;
//对全局变量和全局对象,解除引用 derefrencing 。局部变量会自动被解除引用
解除引用的真正作用是让值脱离执行环境,以便拉机器下次运行时将其回收
myObject.element = null;
element.someObject = null;
第五章 引用类型
2017.2.15
引用类型和类相似,但是不具备传统的面向对象语言所支持的类和接口等基本结构,是一种数据结构,用于将数据和功能组织在一起。
var person = new Object()
Object类型
大多数引用类型值都是Object类型的实例
1) new 的方法
2) 对象字面量
//属性名name可以用使用字符串,也可不使用
var person = {
name: "Nicholas"
};
访问对象属性的方法
1. 点表示法(推荐)
2. 方括号: 优点: 可以通过变量来访问属性,如果属性名包含会导致语法错误的字符(空格)或者使用的是关键字和保留字
Array
与其他语言的差别:
* 每一项可以保存任何类型的数据(第一个位置保存string,第二个保存number)
* 大小可以动态调整
创建方式
1. new Array() || new Array(20) || new Array(“red”, “blue”)
可以省略new 操作符
2. 字面量表示法
```
var colors = ["red", "blue", "green"];
var colors = []
var values = [1,2,];//////这样会创建一个包含2或3项的数组
////主要是IE8以前的版本bug
colors[2] = "black" ////修改
colors[3] = "brown" ///新增
///////////////length
colors.length = 2//////可以删除最后一位
colors.length = 4 ////////////新增的每一项都会取得undefined的值
///////////向末尾添加新项
colors[colors.length] = "brown"
colors[99] = "black" ////////////length是100,其余的值是undefined
```
检测数组(P88)
iE9+
if(Array.isArray(value))
转换方法
所有对象都具有toLocalString(), toString(), valueOf() 方法
toString: 返回数组中每个值的字符串形式拼接而成的以逗号分隔的字符串
valueOf:返回的还是数组
toLocalString: 调用每一项的toLocalString的值
alert(对象)调用的是toString的值
p89的例子
join方法可以使用不同的拼接符,不传入值或者传入undefined,它会使用逗号
栈方法
让数组表现的像栈一样,栈:限制插入和删除项的数据结构。LIFO(Last In First Out)后进先出。(推入和弹出),提供push() 和 pop()
队列方法
队列数据结构的规则是FIFO(First In First Out), 末端添加项,前端移除。shift() 取得第一项,unshift() 向数组前端添加任意个项并返回新数组的长度
IE7 对unshift有bug,返回undefined
重排序方法
会修改数组
reverse() 反转顺序, sort(), 返回值是排序之后的数组
sort 调用toString方法,比较得到的字符串。可以接受一个比较函数作为参数
function compare(value1, value2){
if(value1 < value2}{
return -1;
}else if(value1 > value2){
return 1;
}else{
return 0;
}
}
var values = [0, 1, 5 , 10, 15]
values.sort(compare);
//降序的话只要改变return的返回值
* 第一个参数 位于 第二个 之前---返回负数
* 相等, 返回0
* 第一个 位于 第二个之后 返回正数
对于数值类型或者valueOf方法会返回数值类型的对象类型,可以使用一个更简单的方法
//比较函数通过小于0, 等于0,大于0的值来影响排序结果
function compare(value1, value2){
return value2 - value1;
}
操作方法
concat()
* array.concat() —-复制当前数组并返回副本
* array.concat(array) — 复制每项并添加到末尾
* array.concat(item) – 复制每项并添加到末尾
slice()
splice()
位置方法 ie9+支持
都返回查找项的位置,没找到-1,使用===操作符
indexOf() 从数组开头开始查找
lastIndexOf() 从数组末尾开始查找
迭代方法(P96)ie9+
不会修改数组中包含的值
参数1:在每项上运行的function,参数2:作用域对象(可选),影响this的值
1. every()
2. filter()
3. forEach()
4. map()
5. some()
every和some相似,用于查询数组的项是否满足某个条件,every每项都返回true,这个方法才返回true;some只要某一项返回true
var numbers = [1,2,3,4,5,6,7]
var everyResult = numbers.every(function(item, index, array){
return (item > 2)
});
everyResult //false
filter() 方法,会返回[3,4,5,4,3] 返回符合条件的数组
map() 也返回一个数组,可对结果进行计算
var mapResult = numbers.map(function(){
return item * 2;
})
//mapResult [2,34,6,8,10,12,14]
///////forEach():无返回值,本质与for一样
number.forEach(function(item, index, array){
});
归并方法 ie9+
迭代数组的所有项,然后构建一个最终的返回值
reduce(): 第一项开始到最后
reduceRight():最后一项开始,到第一项
var values = [1, 2, 3, 4, 5];
var sum = values.reduce(function(prev, cur, index, array){
return prev + cur;
});
sum ////// 15
//////////prev = 1, cur = 2开始, prev = 1+2 = 3,
Date
在java.util.Date基础上构建的,使用UTC,1970年1月1日午夜0点开始经过的毫秒数,之前或之后的10.8次
- Date.parse(日期的string)返回毫秒数
美国的日期:月/日/年,英文月名 日,年, ISO8601 扩展格式YYYY-MM-DDTHH:mm:ss:sssZ
var someDate = new Date(Date.parse("May 25, 2004"))
var someDate = new Date("May 25, 2004")//////也可以
转换失败返回NaN - Date.UTC(年份,基于0的月份0-11,天1-31, 小时0-23, 分钟,秒,毫秒数) 年和月必须提供,天默认为1,其他默认为0
//GMT时间 2000年5月5日下午5点55分55秒
new Date(Date.UTC(2000, 4, 5, 17, 55, 55));
//本地时间 2000
new Date(2005, 4,5,17,55,55);
var start = +new Date()//////////ie9+ 支持Date.now(), 不支持的浏览器用+new Date()
Date也有toLocaleString() , toString()方法,但是不同浏览器输出的大不一样,
valueOf()返回毫秒数,可用于比较
var date1 = new Date(2007, 0, 1)
var date2 = new Date(2007, 1, 1);
alert(date1 < date2)
日期格式化方法
表现都不一致
RegExp类型(P103)
正则表达式: var expression = /pattern/ flags
flags:
* g: 全局模式,该模式应用于所有字符串
* i: 不区分大小写
* m: 多行模式?到达一行文本末尾时还会继续查找下一行是否存在匹配项
*
pattern中使用了许多元字符,都必须转义!包括,( [ { \ ^ $ | ) ? * + . ] }
/////1. 字面量形式:
/////匹配'[bc]at'不区分大小写的第一项
var pattern = /\[bc\]at/i;
/////2. RegExp构造函数
new RegExp("[bc]at", "i") === /[bc]at/i
!!!!!!因为RegExp传递的参数是字符串,所以某些要进行双重转义!
\\ ----> \\\\
/\[bc\]at/ === "\\[bc\\]at"
var text = "monm and dad and baby"
var pattern = /mom( and dad( and baby)?)?/gi
var matches = pattern.exec(text)
同一个text上,多次调用exec,使用g的情况下,会继续查找
只想知道目标字符串是否和pattern匹配,可以用test,会返回Boolean
RegExp实例继承了toLocaleString和toString, 返回字面量形式
Function
函数是对象,函数名是指针。
函数声明和函数表达式var a = function …. 的区别:函数表达式不可以提前调用。函数声明会自动提升到源代码的顶部
函数可以作为值传递
function callSomeFunction(someFunction, someArgument){
return someFunction(someArgument);
}
function加了()表示立即执行
函数内部属性
arguments[]
callee:指向拥有arguments对象的函数
function factorial(num){
if(num <= 1){
return 1;
}else{
////return num * factorial(num-1);
////为了消除紧密耦合现象,函数名字如果变了,代码也得改变
return num * arguments.callee(num-1);
}
}
函数的属性和方法 (P116)
属性:
length:希望接收命名参数的个数
prototype
方法
apply()
call()
bind() [ES5] ——-绑定this给function
设置函数体内this对象的值, 区别是接收参数的方式不同
扩充函数赖以运行的作用域
sum.apply(this, [num1, num2]) or
sum.apply(this, arguments)
sum.call(this, num1, num2)//////////每个参数都必须列举出来
基本包装类型
var s1 = “some text”///////////后台会自动创建一个string对象,从而可以调用方法
与new出来的区别是–生存期。new出来的对象会一直保存在内存中,基本包装只存在于执行的瞬间。所以不能添加属性和方法
Number
直接Number(“25”)是转型函数, 返回number,new Number(“25”)构造函数,返回Object
一般没必要用new来创建这些对象
Number的方法
- num.toString(n进制)
- num.toFixed(2)指定小数位
num.toPrecision(n) 根据要处理的数值决定到底是调用toFixed() 还是toExponential(),会通过向上或向下舍入,来最精确表达
String
- 字符方法
charAt():返回字符
charCodeAt(): 返回字符编码
string[1]: 通过编号访问 (ES5) 字符串操作方法
对原始字符串没有影响
concat(): 一般用+
slice(start, end):
substr(start, length):
substring(start, end):字符串位置方法
- trim()方法
- 大小写
- 模式匹配
- localCompare
- fromCharCode
- HTML
- 字符方法