萌新想问一个关于箭头函数 this 的问题,看了好多例子还是理解不了。
代码:
var obj = {
a : 12,
b : () => {console.log(this)},
c : {
d: () => {console.log(this)},
f: function(){console.log(this)}
},
e : function(){console.log(this)}
}
obj.b();
obj.c.d();
obj.c.f();
obj.e();
问题:obj.c.f();
处打印出来的为什么是 window
对象而不是 obj
对象 ?
obj.c.f() 打印的是 c
建议你 Google 一下箭头函数与普通函数的区别。
是 obj.c
不是你说的 window,也不是 obj
obj.c.f() 应该是 c 吧
貌似是打印 obj.c 吧,箭头就是一个语法,看看介绍就明白了
obj.c.f() 打印的是 obj.c 啊...
var obj = {
a : 12,
b : () => {console.log(this)},
c : {
d: () => {console.log(this)},
f: function(){console.log(this); return this;}
},
e : function(){console.log(this)}
}
obj.b();
obj.c.d();
console.log(obj.c.f() === obj.c);
obj.e();
把这坨代码粘贴到 babel 的 playground 里面,你就懂了
楼上正解,c 是普通函数,谁调用它 this 就是谁,所以打印的是 c
而箭头函数中的 this 始终指向自身外的第一个 this,也就是始终等于调用它的函数的 this
打错了,f 是普通函数,谁调用它 this 就是谁,所以打印的是 c
问题:obj.c.d();处打印出来的为什么是 window 对象而不是 obj 对象 ?
你想问的是 obj.c.d() 吧
https://zh.javascript.info/object-methods
1 this 是 function 的关键字,而箭头函数没有这个关键字
2 关键字其实本质上就是函数作用域里的一个变量
因为箭头函数里没有 this, 所以只能向上一层作用域里去找这个变量, 也就是 windows 了
因为 d() 函数的 this 指向它外层的 this
问题变成了 c 的 this 是什么?
如果 c 是一个函数, 那调用 obj.c() , c 里的 this 肯定是 obj.
但是 c 不是一个函数, 它没有 this, obj 也没有 this
所以 d() 的外层的 this 就是 window 对象
这种东西我没 google 过我是不会上来问的,建议你下次不要提这种建议
对的对的
你这 google 能力不行啊,这种问题 google 不出来???
// 你可以拷贝代码 到 jsbin 点 com 运行下试试
// 你不知道 this 是因为 你不用 call
// this 是 fn.call(this) 的 第一个参数
// 这是历史原因,js 作者创造 js 的一个需求就是 要求它像 java
// 所以你会看到很多 java 的面向对象写法,但是如果你是一个 js 程序员 就不会那样用
// 比如 js 你声明数组 var arr = [ ] java 就会这样 var arr = new Array( )
// 比如 var o = {} java 就要 var o = new Object()
// 默认当前环境是浏览器且没用 严格模式
function a(){console.log(this);}
a(); // window
// a() 等价于 a.call(undefined) 所以是 window
a.call(1); // 1
var o = {};
a.call(o); // o
var o2 = {};
o2.a = a;
o2.a(); // o2
console.log('----------华丽的分割线----------')
var b = ()=>{console.log(this);}
b();
b.call(1);
// ES6 的箭头函数干掉了 this 和 arguments 参数
// 所以就算你强行指定 this 也会指向外层的 this
this 指向的固定化,并不是因为箭头函数内部有绑定 this 的机制,实际原因是箭头函数根本没有自己的 this,导致内部的 this 就是外层代码块的 this。正是因为它没有 this,所以也就不能用作构造函数。
所以,箭头函数转成 ES5 的代码如下。
// ES6
function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
// ES5
function foo() {
var _this = this;
setTimeout(function () {
console.log('id:', _this.id);
}, 100);
}
上面代码中,转换后的 ES5 版本清楚地说明了,箭头函数里面根本没有自己的 this,而是引用外层的 this。
http://es6.ruanyifeng.com/#docs/function#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0
箭头函数并没有 this,如果你在箭头函数里写 this,实际上这个 this 属于它外层的普通函数,而不属于这个箭头函数。
Lexical this,是说这段代码的在文法(源码)所在位置是什么 this 就是什么 this。它不是没有 this,只是无法手动 bind。
父级指的是父级函数,不是父级对象。d 那个函数的外层没有其他函数了,直接到顶层就完事了
你来你来,我发现来这里的有一部分回复不将焦点集中在问题上面,而是关注别的问题,解释一下又能怎样,我也不至于是伸手党啊,每个回复我都有好好研究,我连 MDN 都翻了,你跟我说这些对我完全没有意义,以前这种都是不回的,可是见多了真的忍不住....就像是我语气重了一点,依然跟你说多多担待一样,其实也没差~
你要理解对象本身是没有 this 的,箭头函数不会创建自己的 this, 它只会从自己的作用域链的上一层继承 this。那执行 obj.c.d()的时候,由于 c 和 obj 都没有 this,再沿着作用域链往上,console 出来的 this 就是 windows 了
听你这么说,我将代码转成 es5 试了一下,这样是能解释通的,暂时结案吧。欢迎反驳这个回复