箭头函数没有this
!
箭头函数没有this
!!
箭头函数没有this
!!!
重要的事情说三遍!
那你可能要问我在箭头函数中明明可以取到this啊!
function foo() {
this.a = 1
let b = () => console.log(this.a)
b()
}
foo() // 1
以上箭头函数中的
this
其实是父级作用域中的this
,箭头函数引用了父级作用域的变量,构成了一个闭包。
以上代码等价于:
function foo() {
this.a = 1
let self = this
let b = () => console.log(self.a)
b()
}
foo() // 1
箭头函数不仅没有this
,常用的arguments
也没有。如果你能获取到arguments
,那它一定是来自于父级作用域。
function foo() {
return () => console.log(arguments[0])
}
foo(1, 2)(3, 4) // 1
如果箭头函数有arguments
,就应该输出3而不是1。
一个常犯的错误是使用箭头函数定义对象的方法,如:
let a = {
foo: 1,
bar: () => console.log(this.foo)
}
a.bar() //undefined
以上代码中,箭头函数中的this
指向并不是指向a
这个对象。对象a
并不能构成一个作用域,所以再往上到达全局作用域,this
就指向全局作用域。如果我们使用普通函数的定义方法,输出结果就能符合预期,这是因为a.bar()
函数执行时作用域绑定到了a
对象。
let a = {
foo: 1,
bar: function() { console.log(this.foo) }
}
a.bar() // 1
以上文章提到了this
指向和作用域概念,这里进一步介绍下。
this指向
首先必须要说的是,this
的指向在函数定义时是确定不了的,只有函数执行时才能确定,实际上this
最终指向的是调用它的对象。
在函数没有调用时,this的值无法确定。
还是拿例子来说明,
function a(){
var user = "追梦子";
console.log(this.user); //undefined
console.log(this); //Window
}
a();
因为this
最终指向的是调用它的对象,函数a
实际上是被window
调用的。
再来个例子。
var o = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
o.fn();
这里this
指向o
,好像没什么好说的,最终指向调用它的对象。
好了,看到这里还不要骄傲,下面几个例子才有真正的坑。
var o = {
a:10,
b:{
// a:12,
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn();
这是因为this
指向的是上一级调用的对象,而不能一级一级往上寻找。
作用域
刚才讲到普通函数的this指向是运行时确定的,然而,不同的是,
JavaScript中的作用域是的嵌套关系是定义时确定的。
也就是说,JavaScript的作用域是静态作用域,又叫词法作用域,这是因为作用域的嵌套关系在语法分析时就可以确定,而不是在运行时确定。
例如,
var scope = 'top';
var f1 = function() {
console.log(scope);
};
f1(); // 输出 top
var f2 = function() {
var scope = 'f2';
f1();
};
f2(); // 输出 top`
参考
https://jingsam.github.io/2016/12/08/things-you-should-know-about-arrow-functions.html
https://segmentfault.com/a/1190000004589779
https://juejin.im/entry/589be5b1b123db16a3bec5c2
https://juejin.im/post/5aa1eb056fb9a028b77a66fd
https://segmentfault.com/a/1190000018119191