this没有明确的定义,也就意味着this是在运行时确定的,不是在定义时确定的。
误解1:
指向函数自身,看上去很合理。
常用的递归,在函数内部调用自己活是一个在第一次被调用时会解除自己绑定的事件处理器。1
2
3
4
5
6
7
8
9
10
11function foo(num){
console.log(“foo:”+ num);
this.count++;
}
foo.count = 0;
for (var i =0;i < 10;i++) {
if (i > 5) {
foo(i);
}
}
console.log(foo.count); //0 这TM是怎么回事。。。?
— 解:当代码执行foo.count=0;它确实在函数对象foo中加入了一个count属性,但函数内部this.count,this指向的根本不是函数对象,而是window,那么这个是个什么鬼,那window上的count就是正确的执行次数?不,并不是,这个count是全局变量,而且值是NaN,因为刚刚开始this.count值为undefined,这样加上数字就是NaN。
我们可以创建一个对象来持有这个count值。但这是避免了this的问题,这是一个我们便于理解的词法作用域。
注意:在函数中有一个老大但现在被废弃了,而arguments.callee引用也指向当前正在执行的函数的内部。这通常是匿名函数在内部自己访问函数对象的唯一方法,但最佳的是完全避免匿名函数。
还有一种使用函数对象来执行调用。另一种是强制指向函数对象,call调用就好。
误解2:
this不知怎的指向了函数作用域。这种说法有错有对。
明确地说,this不会以任何方式指向函数的此法作用域。作用域好像是一个将所有可用标识符作为属性的对象,从内部看是对的。但JavaScript代码不能访问作用域对象,只是引擎内部实现。1
2
3
4
5
6
7
8
9function foo(){
var a = 2;
this.bar();
}
function() {
console.log(this.a);
}
foo();
— 执行结果无疑:undefined。
中间过程:这个代码不止一个错貌似还阔以执行。
首先,试图通过this.bar();来引用bar()函数。他几乎碰巧能够工作,调用bar最自然方式是避开this。代码想通过this来建立foo和bar之间的桥,使用bar可访问foo内部作用域的a。这样的桥是不可能的,使用this在词法作用域中查找东西,这是不可能的。
到底啥是this?
this不是编写时绑定,而是运行时绑定,依赖函数调用上下文。当函数被调用时,会建立一个活动记录,称为执行上下文环境。包含何处调用,参数等等,属性之一就是this。
this实际上是在函数调用时建立的绑定,它指向什么完全由函数被调用的调用点来决定。