ECMAScript:定义了5种数据类型:Undefined,Null,Boolean,Number和String。
typeof:返回的值有:undefined,boolean,number,string,function,object(引用类型或null类型)
对于未定义的变量使用出typeof之外的运算符都会报错。如下面的语句会报一个错。
var tmp;
tmp1=='undefined';
4.值undefined实际是从null派生而来的,因此以下语句返回true
null==undefined
undfined是声明了变量但未对其初始化时赋予该变量的值,null则用于表示尚未存在的对象
5.对于浮点数,在用它进行计算前,真正存储的是字符串
6.ECMAScript定义的数介于Number.MAX_VALUE和Number.MIN_VALUE之间,但他们的计算结果却可以超过这个范围,当生成的数大于Number.MAX_VALUE时值将被赋值为Number.POSITIVE_INFINITY;当生成的数小于Number.MIN_VALUE时,值将被赋为Number.NEGATIVE_INFINITY,可以通过isFinite函数来测试一个数是否是无穷。
7.一元加法经常被用作将字符串转换为数字。
8.有符号整数用31位表示整数的数值,用第32位表示整数的符号,0表示正数,1表示负数。
9.负数采用的形式是二进制补码。计算数字二进制补码的步骤有:
1) 确定该数字的非负版本的二进制表示
2) 求得二进制反码,即要把0替换为1,把1替换为0
3) 在二进制反码上加1
10.任何一个数字和字符串比较,字符串都将被转换为数字,但两个字符串的数字被比较时,两者都以字符串的形式比较。
11.arguments,以数组的形式访问函数的变量
12.Function对象的length属性是指函数函数期望的参数的个数。
13. javascript虽然是解释执行的,但也不是按部就班逐句解释执行的,在真正解释执行之前,javascript解释器会预解析代码,将变量、函数声明提前解释,这就意味着我们可以在function声明之前调用function,这多数人习以为常,但是对于变量的定义与解析咋一看会很奇怪。
console.log(a);//undefined
vara=3;
console.log(a);//3
console.log(b); //Uncaught ReferenceError: b is not defined
上面代码在执行var a=3;的声明部分就已经得到预解析(但是不执行赋值语句),所以第一次的时候会是undefined而不会报错,执行过赋值语句会得到3,上段代码去掉最后一句和下面代码是一样的效果。
var a;
console.log(a);//undefined
a=3;
console.log(a);//3
执行环境(运行期上下文):定义了变量或函数有权访问的其他数据,决定了它们的各自行为。每个执行环境都有一个与之关联的变量对象,执行环境中定义的所有变量和函数都会保存在这个对象中,解释器在处理数据的时候就会访问这个内部对象。
作用域链:当代码在一个环境中执行时,会创建变量对象的一个作用域链来保证对执行环境有权访问的变量和函数的有序访问。作用域第一个对象始终是当前执行代码所在环境的变量对象。eg:
function a(x,y){
var b=x+y;
return b;
}
在函数创建a的时候它的作用域链填入全局对象,全局对象中有所有全局变量
如果执行环境是函数,那么将其活动对象作为作用域链的第一个对象,第二个对象是包含环境,下一个是包含环境的包含环境……
var total=a(5,10);
这时候var total=a(5,10);语句的作用域链如下:
在函数运行过程中标识符的解析是沿着作用域链一级一级搜索的过程,从第一个对象开始,主机向后回溯,直到找到同名标识符为止,找到后不再继续遍历,找不到就报错。
16. 闭包:只要存在调用内部函数的可能,javascript就需要保留被引用的函数。而且javascript运行时需要跟踪引用这个内部函数的所有变量,直到最后一个变量被废弃,javascript的垃圾收集器才能释放相应的内存空间。父函数定义的变量在子函数的作用域链中,子函数没有被销毁,其作用域中所有变量和函数就会被维护,不会被销毁
for(vari=0;i<elements.length;i++){
elements[i].onclick=function(){
alert(i);
}
}
每次element点击alert都是length,这段代码中element绑定的click事件处理程序的作用域链是这样的:
由于内部函数(onclick事件处理程序时刻有调用可能),所以其作用域链不能被销毁,i的值一直保持for循环执行完后的length值,所以每次触发onclick的时候才会alert length
for(vari=0;i<elements.length;i++){
(function(n){
elements[n].onclick=function(){
alert(n);
}
})(i);
}
为什么这样就行了呢,这时候onclick引用的变量变成了n,而由于立即执行函数的原因,每个onclick函数在作用域链中分别保持着对应的n(0~length-1),这时候就可以了。
从上面的例子可以看出。闭包函数保持其作用域的所有变量及函数在内存中,内存消耗很大,在使用的时候尽量销毁父函数不再使用的变量。