温馨提示:作者的爬坑记录,对你等大神完全没有价值,别在我这浪费生命
这一切,源于阮大神博文学习Javascript闭包(Closure)- 阮一峰中的一道思考题
//问题1:
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());
这道题,出现在了关于闭包的博文之中,而阮大神的一句“如果你能理解下面两段代码的运行结果,应该就算理解闭包的运行机制了。”彻底激发了我的斗志。
乍一看,外面一个变量叫name
,对象内还有一个变量是name
这就很明显了,这就是在考察对于作用域链的理解了,这里返回的应该是一个妥妥的“My Object”,
可是运行结果却狠狠大打了我的脸,但是弹出的一个大大“The Window”让我不得不重新面对这一段代码,这里面的this
指得到底是什么?
进一步尝试,将this
打印到控制台上出现的结果是“window”,这下就明白了,问题就出在了this
上,它并没有按照我所想的去指向了object
而是指向了全局对象window
这就是为什么会返回“The Window”了
//在这里,把this
去掉也会返回“My Object”具体原因还没整明白以后补充
再看阮大神给出的第二道题就更懵逼了
//问题2:
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()());//My Object
按照这几行代码的意思,在getNameFunc
的this
指向的是object
而在其内部的函数中,则会指向全局对象,这去哪说理,再次又开始狂搜博文
Javascript的this用法 - 阮一峰
彻底理解js中this的指向,不必硬背。- 追梦子
JS 中 this 关键字详解 - 苹果小萝卜
JavaScript中知而不全的this - Snandy
看了一圈,心里算是有了普,get到了一个基本的概念
this指向的是调用它的对象
这也就是说,在对象定义的时候this
并没有一个具体的指向,只有当被调用时,this才会被赋值给调用他的对象,了解了这个概念,再回头看看第一题,还是有问题这句object.getNameFunc()()
在执行的时候到底发生了什么,我们对第一题做一些改变
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
console.log(this.name)
return function(){
console.log(this.name)
return this.name;
};
}
};
object.getNameFunc()//My Object 执行语句1
object.getNameFunc()()//The Window 执行语句2
在执行语句1中,可以理解getNameFunc()
是被object
对象所调用,在函数中的this
就指向了object
,所以就出现了这个结果,
在执行语句2中,我们可以理解为执行语句1的返回函数,被执行了一次,而执行它的就是我们的window对象了,为了便于理解我们把执行语句2进行改写
var getVal = object.getNameFunc()
getVal()//The Window
实际上,执行语句2就是执行了getVal()
而这个函数的执行对象是window,所以就出现了上文中的结果。
我们再来看问题2就很明白了var that = this;
是在object.getNameFunc()
执行的过程中被执行的,所以这里的this
指向的就是object
而把他赋值给变量that
后实际上就是把object
赋值给了that
(有不严谨之处,领会精神),而由于that
处于内部函数的作用域链中,不能被释放,连同返回的内部函数形成闭包(终于见到你了),所以一直都指向了object
,所以题目2的最终结果就是“My Object”了
长出一口气
这么看this这个概念很是神奇,并且包含了许多对象方面的知识,使我不禁对彻底弄明白他的各种应用方法和原理产生了不切实际的幻想,那么交给写后文的未来的我去梳理把
能看到这的都是真爱
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。