this词法
ES6添加了一个特殊的词法形式的函数声明,叫做箭头函数,箭头函数在涉及this绑定的行为和普通函数的行为完全不一样,他放弃了所有的普通函数this绑定的规则,取而代之的是用当前的词法作用域覆盖了this原本的值。
var obj = {
count: 0,
cool: function coolFn() {
if(this.count < 1) {
setTimeout(() => {
this.count++;
console.log('awesome?');
},1000);
}
}
}
obj.cool();//awesome?
这个箭头函数中的this直接是cool()的this绑定(因此调用它并不会出错)
它将程序员们经常犯的一个错误给标准化了,也就是混淆了this绑定规则和词法作用域规则。
另一个导致箭头函数不够理想的原因是他不是具名的,而是一个匿名函数。
误解:
- 人们很容易把this理解成指向函数自身。那么为什么函数要从内部引用函数自身呢?常见的原因是递归(从函数内部调用这个函数)或者可以写在第一次被调用后自己解除绑定事件处理器。
- 新手通常会认为,既然把函数看做一个对象,那就可以在调用函数时储存状态。
call
function foo(num) {
console.log("foo" + num);
this.count ++;
}
foo.count = 0;
var i;
for(i = 0; i < 10; i++){
if(i > 5) {
// 使用call(...) 可以确保this指向函数本身
foo.call(foo, i)
}
}
// foo: 6
// foo: 7
// foo: 8
// foo: 9
cnosole.log(foo.count); // 4
它的作用域
还有一种常见的错误是,this指向函数的作用域。这个问题在某中情况下是正确的,但是有时候又是错误的。需要明确的是this在任何情况下都不指向函数的词法作域。
function foo(){
var a = 2;
this.bar(); // 能调用到bar也是意外,正常应该通过词法作用域,直接执行
}
function bar(){
console.log(this.a)
}
foo(); // a not defined
==当你想把this和词法作用域的查找混合使用的时候,一定要提醒自己这是无法实现的==
是什么
this不是在写代码时候绑定的而是代码在执行的时候绑定的,它的上下文取决于函数调用时的各种条件。
this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。
==当一个函数被执行时,会创建一个活动记录(有时候也被称之为执行上下文)。这个记录会包含函数在哪里被调用、函数的调用方式、传入参数等信息。this就是这个记录的一个属性,会在函数执行的过程中调用到。==
this实际上是在函数被调用的时候发生绑定,他指向什么完全取决于函数在哪里被调用。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 chenMing!