间接实现访问控制:(父对象读取不了子对象的变量,但是子对象可以读取父对象的变量)
var foo = ( function() {
var secret = 'secret';
// “闭包”内的函数可以访问 secret 变量,而 secret 变量对于外部却是隐藏的
return {
get_secret: function () {
// 通过定义的接口来访问 secret
return secret;
},
new_secret: function ( new_secret ) {
// 通过定义的接口来修改 secret
secret = new_secret;
}
};
} () );
foo.get_secret (); // 得到 'secret'
foo.secret; // Type error,访问不能
foo.new_secret ('a new secret'); // 通过函数接口,我们访问并修改了 secret 变量
foo.get_secret (); // 得到 'a new secret'
闭包的作用:
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以 读取/修改 函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
function f1(){
var n=999;
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000
为什么局部变量n会一直保存在内存中呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
this在不同环境下的结果:
var object={name:'my object',getName:function(){
var that=this; // 提前赋值,避免了环境切换导致的变异。
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