对于箭头函数里的 this
先说总结:
- 箭头函数没有本人的 this、arguments,箭头函数里的 this 用的是 parent 作用域的 this。
- 箭头函数里的 this 是词法作用域,是由代码构造决定的,跟在哪里调用无关,与箭头函数在代码里的地位无关。
- 确定箭头函数里 this 的指向,能够动态剖析代码构造,始终往上找 function,如果有,就是最近的 function 里的 this,如果到最外层都没有,就是 window。
- 箭头函数的 this,一旦确定后是不可更改的。
记住,箭头函数里的 this 是能够动态剖析的,然而函数里的 this 又齐全不一样了
上面开始注释
箭头函数没有本人的 this、arguments,箭头函数里的 this 用的是 parent 作用域的 this。
廖雪峰的文章说,箭头函数里的 this 是词法作用域。
那么就是 由代码构造决定的,跟在哪里调用无关,事实证明也是这样的。
箭头函数呈现的地位有两种:
- 在对象里
- 在函数里
箭头函数在对象里
var obj = {
param: 123,
ff : () => console.log(this), // window, strict 模式下是 undefined
}
因为箭头函数没有本人的 this,会去找 parent 的 this,然而对象不形成独自的作用域,没有词法作用域,所以持续往上找 parent,就找到了全局作用域。
通过 babel 编译,发现间接就把 this 替换成了 undefined
// bebal 编译后的后果
// void 0 就是 undefined
"use strict";
var _this = void 0;
var obj = {
param: 123,
ff: function ff() {return console.log(_this);
}
};
箭头函数在函数里
function test () {
let param = 5656;
let ff = () => console.log(this);
}
箭头函数的 this 是词法作用域,词法作用域是跟代码构造相干的,那么是能够动态剖析的。
因为是词法作用域,那么 箭头函数里的 this 跟在哪里调用无关,与箭头函数在代码里的地位无关。
咱们剖析一下,箭头函数没有本人的 this,会找 parent 的 this,它的 parent 的是 test 函数,函数是有作用域的,有词法作用域,所以 test 里的 this 就是箭头函数的 this。
也就是 箭头函数里的 this,通过动态剖析,会始终往上找 function,找到了,就用最近的 function 里的 this,找不到,就用 window。
通过 babel 编译一下,发现箭头函数的 this 即是 test 函数里的 this:
"use strict";
function test() {
var _this = this;
var param = 5656;
var ff = function ff() {return console.log(_this); // 这里的 this 取的是 test 函数的 this
};
}
因为箭头函数和 test 函数的 this 是一样的,那么如果 test 函数里的 this 变动了,那么箭头函数的 this 也会跟着变动。比方看这个例子:
let obj = {
param: 123,
ff: function () {let rr = () => console.log(this);
rr();}
}
obj.ff(); // obj,因为这时 ff 函数里的 this 是 obj 对象
let tt = obj.ff;
tt(); // window,因为这时 ff 函数里的 this 是全局对象
这个通过 babel 编译后的后果是:
"use strict";
var obj = {
param: 123,
ff: function ff() {
var _this = this;
var rr = function rr() {return console.log(_this);
};
rr();}
};
obj.ff();
var tt = obj.ff;
tt();
留神,箭头函数的 this,一旦确定后是不可更改的
这句的了解是:箭头函数的 this 一旦确定,就不能更改了,典型的如在 setTimeout
函数里用箭头函数。要辨别下面的状况,箭头函数 rr
的 this 取的是 ff
函数的 this,然而 ff
函数的 this 是没有确定的,运行起来后 ff
函数的 this 才确定。
function test () {return () => console.log(this);
}
let obj = {aa: 123,}
let rr = test.call(obj);
setTimeout(rr,1000); // obj,而不是 window 因为箭头函数 rr 的 this 曾经确定了,前面不能更改
多层嵌套的状况
let obj = {ff1: function () {
let obj2 = {ff2: () => console.log(this),
obj3: new Object(() => console.log(this))
};
return obj2;
},
fun1: function (){return function fun2(){return function fun3(){return () => console.log(this);
}
}
}
}
obj.ff1().ff2(); // obj, 取的 ff1 的 this
obj.fun1()()()(); // window,取的 fun3 的 this,因为嵌套函数的 this 不能继承,所以是 window
箭头函数 ff2
里的 this,向上找 parent,obj2 是对象没有作用域,持续向上,找到 ff1
函数,于是箭头函数 ff2
的 this 就是取 ff1
函数的 this。obj3 的 new Object()的传参是箭头函数,外面的 this 实用的规定也一样,也是始终向上找 parent,最初是 ff1
函数的 this,看 babel 的转换的代码就晓得了。
"use strict";
var obj = {ff1: function ff1() {
var _this = this;
var obj2 = {ff2: function ff2() {return console.log(_this);
},
obj3: new Object(function () {return console.log(_this); // 取的是 ff1 的 this
})
};
return obj2;
},
fun1: function fun1() {return function fun2() {return function fun3() {
var _this2 = this;
return function () {return console.log(_this2);
};
};
};
}
};
obj.ff1().ff2(); // obj, 取的 ff1 的 this
obj.fun1()()()(); //
总结
- 箭头函数没有本人的 this、arguments,箭头函数里的 this 用的是 parent 作用域的 this。
- 箭头函数里的 this 是词法作用域,是由代码构造决定的,跟在哪里调用无关,与箭头函数在代码里的地位无关。
- 确定箭头函数里 this 的指向,是动态剖析代码构造,始终往上找 function,如果有,就是最近的 function 里的 this,如果到最外层都没有,就是 window。
- 箭头函数的 this,一旦确定后是不可更改的。
记住,箭头函数里的 this 是能够动态剖析的,然而函数里的 this 又齐全不一样了