var obj = {
a:3,
b:function(){
console.log(this,1);
var that = this;
var s = function(){
console.log(this,2);
console.log(that,3);
}
return s;
}
}
obj.b()();
来,求大神解释一下,为什么第二个输出是全局对象。this不应该访问的是父级内的this么?
继续再追问一下
var obj = {
a:3,
b:function(){
console.log(this,1);
var that = this;
var s = function(){
console.log(this,2);
console.log(that,3);
}
s();
}
}
obj.b();
这种情况下,2为什么也是window呢?
其实这里就是
this
的隐式丢失了。一个隐式丢失的过程是这样子的:
可以这样理解,
this
词法是跟调用的方式有关的,当调用obj.a()
的时候,这个函数是基于obj
对象来调用的,它作为对象的方法来调用,所以很显然this
指向obj
。而
var b = obj.a
其实就等价于:于是当你调用
b
的时候,这是对b
的直接调用,故指向window
。所以再看回你的代码。
当你
return
了一个函数时,这里创建了一个闭包,that
保存了对词法作用域的引用。这个时候,
obj.b()
就等价于又因为创建了闭包,所以
that
能够访问得到原来的词法作用域。但是这里的this
跟函数调用的方法有关,它相当于直接调用了一个s
函数,所以this
自然指向window
。你可以去看下《你不知道的JS(上卷)》,里面
this
一节讲得十分清楚。补充第二段代码解释:
其实这就是对函数的独立调用,默认绑定到了
window
对象上面。刚刚的说法有点小错误。
this
词法与函数调用的位置和调用的方式有关。一般情况下,都是先找到函数调用的位置,再判断调用的方式。按照你的代码,其实就是两种方式。
window
,严格模式下指向的是undefined
。综上,第一段代码,就是隐式丢失的情况。第二段代码,仅仅只是对于函数的独立调用,虽然是在
obj
中的b
被调用的,仅此而已。