首页 > 代码库 > Javascript (ECMAScript5) 的细节和违反直觉的地方
Javascript (ECMAScript5) 的细节和违反直觉的地方
记录在学习Javascript (ECMAScript5) 中的一些与其他语言的不同之处,本文会不断更新。
里面的知识可能并不太适合有一定经验的Javascript程序员,仅仅但不限于给初学者阅读。
1. null 是一个表示“空”的对象指针
var foo = null
console.log(typeof foo) //输出 object 而不是你所认为的 null
2. undefined 是 null 派生而来的
console.log(null == undefined) //输出 true
3. 浮点数值计算误差问题
var a = 0.1 var b = 0.3 if (a+b == 0.3){ alert(‘OK‘) //然而a+b将会等于 0.300000000000000004 }
当然不仅仅只是ECMAscript有这种问题,很多使用相同数值类型的也有
4.NaN 不等于任何值,包括自身
NaN == NaN //false NaN == "NaN" //false NaN == 0 //false //当然了你可以使用 isNaN 函数
5.for in 语句是没有顺序的代送
6.switch 可以是任何对象比较,不同与 C/C++ 或 Java 7 等里面不能字符串比较
7.所有函数的参数传参都是按值传的,哪怕传入的是对象,也会复制引用指针
function setName(obj){ //这个obj 是复制的引用指针,指向A obj.name = ‘OneName‘ obj = new Object(); //B 但是现在你改变了这个复制的引用指针 指向B obj.name = ‘TwoName‘ //设置的仅仅是B } var p = new Object() // A setName(p) alert(p.name) // 输出 OneName
8.Javascript 没有块级作用域(暂时不讨论闭包等)
你可能认为 两个{}大括号之间属于作用域区,这是Java的经验,然而在Javascript这点并没有得到实现
if (true){ var name = ‘YouName‘ ; } alert(name); // 依然可以得到输出 YouName for(var i=0;i<5;i++){ i++; } alert(i); //依然可以得到 变量 i
9.使用对象字面量表示法定义的对象,实际上将不会调用Object构造函数,推荐只用于只读的业务使用。
var p = {}; // 与 new Object() 得到的结果相同,但不会调用构造函数 p.name = ‘YouName‘; //依然可以想类一样操作 var obj = { name: ‘Name‘ die: function(){//foo} } //一样
10. 直接指向对象,而不是指向下一个引用
var A = function(){ alert(‘Run‘); } var C = A; A = null; //链表的经验可能会告诉我们C将会失效指向null C() //依然正常运行,不影响
11.谜一般的 this 指针究竟指向什么?
function func (A,B){ alert(this) return A+B; } var A = 1; var B = 2; func(A,B); //调用函数 alert输出 window //事实上这就相当于默认调用了 this值将会绑定到 global func.call(window,A,B) //alert输出 window func.call(undefined,A,B) //alert输出 undefined func.apply(new Object(),[A,B]) //输出 Object
//这个第一项参数就是this值
在不同环境下执行函数将得到不同的this值,这里是全局环境,所以this绑定到全局global对象,所以直接调用将是window,如果你再其他环境下调用,那么就将是其他值了。
如果你这样,函数有所属对象时,this绑定到所属对象上去
var obj = new Object(); obj.fun = function(){ console.log(this); } obj.fun(); //调用,此时this值将绑定到 obj 上面去,即this就是obj
所谓绑定,其实就是 function所有的bind() 函数。
var o = {color:‘red‘}; function sayColor() { console.log(this.color); } window.color=‘undefined‘ var A = sayColor.bind(o); //一旦你这样显式的绑定了之后,不论环境怎么样,一定是你绑定的对象为this A() //这里会输出 red 而不是 全局对象color的 undefined
让我们回到this主题:
情况一:普通的函数调用( func(A,B,C,D,....); ) this绑定到全局global 对象。
情况二:作为对象方法的调用 ( obj.func(A,B,C,...) ) this绑定到所附属的对象上。
情况三:作为构造函数调用(var obj = new YourObject()) this绑定到新构造出现的对象(obj)上。
情况四:显示绑定(bind apply call等) this绑定到你指定的对方。
12. 未完待续,还将不断更新....
Javascript (ECMAScript5) 的细节和违反直觉的地方