7.2 閉包 183
1
2
3
4
5
13
6
7
8
9
10
11
12
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()()); //\"My Object\"
ThisObjectExample02.htm
代碼中突出的行展示了這個(gè)例子與前一個(gè)例子之間的不同之處。在定義匿名函數(shù)之前,我們把 this
對(duì)象賦值給了一個(gè)名叫 that 的變量。而在定義了閉包之后,閉包也可以訪(fǎng)問(wèn)這個(gè)變量,因?yàn)樗俏覀?/p>
在包含函數(shù)中特意聲名的一個(gè)變量。即使在函數(shù)返回之后,that 也仍然引用著 object,所以調(diào)用
object.getNameFunc()()就返回了\"My Object\"。
this 和 arguments 也存在同樣的問(wèn)題。如果想訪(fǎng)問(wèn)作用域中的 arguments 對(duì)
象,必須將對(duì)該對(duì)象的引用保存到另一個(gè)閉包能夠訪(fǎng)問(wèn)的變量中。
在幾種特殊情況下,this 的值可能會(huì)意外地改變。比如,下面的代碼是修改前面例子的結(jié)果。
var name = \"The Window\";
var object = {
name : \"My Object\",
getName: function(){
return this.name;
}
};
這里的 getName()方法只簡(jiǎn)單地返回 this.name 的值。以下是幾種調(diào)用 object.getName()的
方式以及各自的結(jié)果。
object.getName(); //\"My Object\"
(object.getName)(); //\"My Object\"
(object.getName = object.getName)(); //\"The Window\",在非嚴(yán)格模式下
ThisObjectExample03.htm
第一行代碼跟平常一樣調(diào)用了 object.getName(),返回的是\"My Object\",因?yàn)?this.name
就是 object.name。第二行代碼在調(diào)用這個(gè)方法前先給它加上了括號(hào)。雖然加上括號(hào)之后,就好像只
是在引用一個(gè)函數(shù),但 this 的值得到了維持,因?yàn)?object.getName 和(object.getName)的定義
是相同的。第三行代碼先執(zhí)行了一條賦值語(yǔ)句,然后再調(diào)用賦值后的結(jié)果。因?yàn)檫@個(gè)賦值表達(dá)式的值是
函數(shù)本身,所以 this 的值不能得到維持,結(jié)果就返回了\"The Window\"。
當(dāng)然,你不大可能會(huì)像第二行和第三行代碼一樣調(diào)用這個(gè)方法。不過(guò),這個(gè)例子有助于說(shuō)明即使是
語(yǔ)法的細(xì)微變化,都有可能意外改變 this 的值。
7.2.3 內(nèi)存泄漏
由于 IE9 之前的版本對(duì) JScript 對(duì)象和 COM 對(duì)象使用不同的垃圾收集例程(第 4 章曾經(jīng)討論過(guò)),
圖靈社區(qū)會(huì)員 StinkBC(StinkBC@gmail.com) 專(zhuān)享 尊重版權(quán)