ES6箭头函数没出现之前,this的指向不是函数被创建时绑定,而是被怎么样的方式调用时绑定的。而箭头函数刚好相反,箭头函数的this指向是函数被创建时绑定的,它的指向就是当前词法作用域中的this,并且不会因为被怎么样的方式调用改变绑定。
什么是词法作用域
首先我们必须了解JS的词法作用域,词法作用域是作用域的其中一个工作模型(另外一个是动态作用域,在js中只有this涉及动态作用域),词法作用域主要在代码的编译阶段,一个变量和函数的词法作用域取决于该变量和函数声明的地方。(而动态作用域是取决于变量和函数被调用的地方)。
var str = 'window';
const obj = {
str: 'obj',
nativeFn: function() {
console.log('当前的this指向', this.str);
return function() {
console.log('原生函数', this.str);
}
},
arrowFn: function() {
console.log('当前的this指向', this.str);
return () => {
console.log('箭头函数', this.str);
}
}
};
const obj2 = {
str: 'obj2'
}
var nativeFn = obj.nativeFn(); //当前的this指向 obj
var arrowFn = obj.arrowFn(); //当前的this指向 obj
nativeFn(); //原生函数 window
arrowFn(); //箭头函数 obj
var str = 'window';
const obj = {
str: 'obj',
foo() {
var str = 2
console.log(this.str); //obj
setTimeout(() => {
console.log(this.str); //obj
}, 100);
}
}
obj.foo();
var str = 'window';
const obj = {
str: 'obj',
fn: () => {
console.log(this.str);
}
}
obj.fn(); //window
这里有些人就迷惑了,竟然是'window',我们知道JS是没有快级作用域的,只有函数作用域和全局作用域,fn函数在创建的时候词法作用域为全局作用域,也就是window,所以箭头函数fn里面的this指向的也就是window.
var obj = {
b: this, //window{}
fn: function() {
return () => {
console.log(this.b);
}
}
}
console.log(obj.b); //window{}
var fn3 = obj.fn();
fn3(); //window{}
通过上面我们可以看到,this其实绑定的就是window对象,所以验证了obj对象里面的词法作用域是window,所以就很好理解了.
普通函数中this(动态作用域)
- 总是代表着它的直接调用者
- 严格模式下(设置了'use strict'),this为undefined
- 当使用call,apply,bind(ES5新增)绑定的,this指向绑定对象
ES6箭头函数中this(词法作用域)
- this指向的是当前的词法环境
- 即使是call,apply,bind等方法也不能改变箭头函数this的指向