您的位置:首页 > Web前端 > JavaScript

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

2015-12-08 22:27 661 查看
阮一峰博客:《学习Javascript闭包》章节中最后有个思考题:

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

代码片段一

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息