这段代码为什么会调用全局的name;this指向怎么不是这个object对象呢?
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()()); //输出 The Window
这代码就指向了这个对象,不理解其中的奥秘?
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()()); // 输出 My Object
首先,请记住在function () {}
内的this
是延迟绑定的,而ES2015
的箭头函数中的this
,是已经被绑定好的,this
取决于定义时this
的指向,相当于function (){}.bind(this)
。this
的指向只有两种情况:
object.fun()
,就像题主说的第二种情况:
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
这种情况下this
指向的是其.
之前的那个对象,这一点同样适用于全局中的函数,因为我们在全局中定义函数,相当于给我们的全局变量添加方法,在浏览器中看也就是给我们的window
添加方法,所以这种方法内的this
,指向.
之前的对象也就是window
。
第一种情况:
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
调用obj.getNameFunc()
返回了一个函数,被添加为了全局方法,所以指向的是window
。
this
指向null
时,在非严格模式下会被转为指向全局:
在看题主的这一段代码时,我们首先一个概念,那就是活动对象,也就是AO
,这个对象是虚拟出来的,在外界访问不到,也就是我说的null
的情况,AO
在我们调用函数时生成,我们在函数内定义的变量可以理解为这个对象的属性,argumenst
也可以理解为AO
对象的属性,但是这个AO
对象在外界访问时为null
,所以题主在getNameFunc
内定义函数相当于给getNameFunc
函数的AO
添加方法,由于AO
对象在外界看来为null
,所以在调用函数时this
指向null
,非严格模式下指向全局。
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
}();
}
};
这种情况下,this
指向的也是全局,用我说的情况2就可以解释。
个人理解,欢迎拍砖与讨论。
对于javascript中this的问题太多了,,,看多了容易混乱,就记住几个重点就好了: 1.this的指向是在运行时决定的,函数中的this,谁调用的他,他就指向谁。 2.bind,call,apply可以改变this的指向。3.ES6的箭头函数中的this是定义时就绑定了的。另外一点和this无关和你这个例子有些关系的就是:函数会创建新的作用域。
this
这个关键字指代的内容是一直都在变动的,随着this
所在的代码块的不同,this
指代的也不尽相同。
第一段代码里,getNameFunc
里面又嵌套了一个匿名的function
,这意味着其实每次执行的匿名的function
都是一个“新生成“的function
,这个”新生成“的function
所在的执行上下文就是window
(这与你代码如何嵌套无关),所以匿名function
内的this
指代的就是window
。
另外一点,在浏览器环境下,你的脚本声明的所有全局变量,实际上都是window
对象的属性,所以var name="The window"
实际上就等同于window.name="The window"
。
第二段代码,var that=this
的作用,是把getNameFunc
的执行上下文传递给”新生成“的匿名function
,that
指代了object
,因此匿名function
的作用跟你再在外面写个funcion(){return object.name}
是一样的。
看了楼上几位前辈的答案,我也来做个简单粗暴的回答吧..
1、函数体中的this指向调用该函数的对象(除了call,apply等特殊情况)。
2、函数体中的return放在函数调用的地方。
所以你代码中的第一种情况:
alert(object.getNameFunc()());
等同于
alert((function(){return this.name;})());
所以该函数执行的时候,函数体中的this在非严格模式下会被转为指向全局(引用@zp1996),弹出window.name
第二种情况:
在执行 var that = this; 这条语句的时候,this指向的是调用 getNameFunc 方法的对象,即object。
所以 that 也指向object
代码中并没有其他地方改变了that的指向,所以在执行 return that.name; 时,that依旧指向object,与this无关。