間接實(shí)現(xiàn)訪問(wèn)控制:(父對(duì)象讀取不了子對(duì)象的變量柏腻,但是子對(duì)象可以讀取父對(duì)象的變量)
var foo = ( function() {
var secret = 'secret';
// “閉包”內(nèi)的函數(shù)可以訪問(wèn) secret 變量,而 secret 變量對(duì)于外部卻是隱藏的
return {
get_secret: function () {
// 通過(guò)定義的接口來(lái)訪問(wèn) secret
return secret;
},
new_secret: function ( new_secret ) {
// 通過(guò)定義的接口來(lái)修改 secret
secret = new_secret;
}
};
} () );
foo.get_secret (); // 得到 'secret'
foo.secret; // Type error,訪問(wèn)不能
foo.new_secret ('a new secret'); // 通過(guò)函數(shù)接口,我們?cè)L問(wèn)并修改了 secret 變量
foo.get_secret (); // 得到 'a new secret'
閉包的作用:
閉包可以用在許多地方被济。它的最大用處有兩個(gè),一個(gè)是前面提到的可以 讀取/修改 函數(shù)內(nèi)部的變量涧团,另一個(gè)就是讓這些變量的值始終保持在內(nèi)存中只磷。
function f1(){
var n=999;
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000
為什么局部變量n會(huì)一直保存在內(nèi)存中呢?原因就在于f1是f2的父函數(shù)泌绣,而f2被賦給了一個(gè)全局變量钮追,這導(dǎo)致f2始終在內(nèi)存中,而f2的存在依賴(lài)于f1阿迈,因此f1也始終在內(nèi)存中元媚,不會(huì)在調(diào)用結(jié)束后,被垃圾回收機(jī)制(garbage collection)回收苗沧。
this在不同環(huán)境下的結(jié)果:
var object={name:'my object',getName:function(){
var that=this; // 提前賦值刊棕,避免了環(huán)境切換導(dǎo)致的變異。
return function(){return that.name;
};
}
}
console.log(object.getName()()); // my object
var object={name:'my object',getName:function(){
return function(){return this.name;
};
}
}
console.log(object.getName()()); // The window