关于阮一峰博客《学习Javascript闭包》章节中最后两个思考题

阮一峰博客:《学习Javascript闭包》章节中最后有个思考题:(网址:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html)

如果你能理解下面两段代码的运行结果,应该就算理解闭包的运行机制了。

 

代码片段一

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

其实个人感觉这个思考题跟闭包关系不大,主要还是this关键字的理解。

首先看看this的定义:this是包含它的函数作为方法被调用时所属的对象。

也就是说 this实际上是一个对象,通俗的说就是当前的对象。

先看以下精简版的代码:

var test = {
intest: function() {
alert(this); //[object Object]
return function() {
alert(this); //[object Window]
return function() {
alert(this); //[object Window]
}
};
}
}
test.intest()()();

通过三个alert可以发现,第一个输出的是[object Object],所以这个this指的是一个object对象,就是声明的test,后两个都是输出[object Window],所以两个this指的都是window对象。

为什么第一个第一个this跟后两个this指的对象不一样呢?这个还是得看this的定义:this是包含它的函数作为方法被调用时所属的对象。也就是说包含this的函数作为方法被调用的时候才是指的“那个所谓的所属对象”。正如例子中第一个this所在的函数”function(){}”是test对象中的一个方法intest。之后两个this所在的函数实际上就是匿名函数。《javascript权威指南》第五版有云:如果包含它的函数作为函数被调用的时候,this指的是全局对象。

单从概念上看理解上太费劲,其实从我自己归纳的角度来说的话,如果包含this所在的函数直接包含在一个具体对象(就是这种形式的东东:var xxx={})中,那么这个this就是指这个具体对象,否则就是指的是全局对象。再精简一点,但从表面上看,就是如果这个函数在xxx={}中,并且在冒号之后,那么他的this就是指的这个具体对象。

接下来再通过代码证明:

str = “window”;
alert(this.str); //window
var test = {
str: “test”,
intest: function() {
alert(this); //[object Object]
alert(this.str); //test
return function() {
alert(this); //[object Window]
alert(this.str); //window
var test2 = {
str: “test2”,
intest2: function() {
alert(this); //[object Window]
alert(this.str); //test2
}
}
test2.intest2();

};
}
}
test.intest()();

看,第三个this又变成[object Object]了~~~并且输出的str是test2。

再写段代码证明:包含this所在的函数不是直接包含在一个具体对象(就是这种形式的东东:var xxx={})中,this指的是全局对象这个结论。

str = “window”;
alert(this.str); //window
var test = function() {
this.str = “test”;
alert(this); //[object Window]
alert(this.str); //test
intest = function() {
this.str = “intest”;
alert(this); //[object Window]
alert(this.str); //intest
}
intest();
}
test();

通过输出可以看出this指的都是指的window对象,this.str可以改变全局变量str的值。

看到这里,阮老师留下的思考题就知道怎么回事了吧。关键点就是第二段代码里把那个this赋值给that了。

再进一步做个探讨吧,纯粹是写着玩:

如果把上段代码最后一行的test()改成new test();

str = “window”;
alert(this.str); //window
var test = function() {
this.str = “test”;
alert(this); //[object Object]
alert(this.str); //test

alert(str); //window
intest = function() {
this.str = “intest”;
alert(this); //[object Window]
alert(this.str); //intest
}
intest();
}
new test();

通过new关键字,可以把test改成那个对象模式了,就是这种 var xxx={}样式的东西。他所直接包含的this指的是当前对象本身。这是因为new关键字又重新创建看一个新的object对象,具体请看这篇文章里关于new的解释:http://web.zhaicool.net/419.html

未经允许不得转载:前端撸码笔记 » 关于阮一峰博客《学习Javascript闭包》章节中最后两个思考题

上一篇:

下一篇: