标签:mozilla 通过 结束 允许 特殊 javascrip 理解 对象 全局变量
闭包是一个比较容易搞混的地方,不知道闭包是干嘛的就强行学习,结果只能学个不明不白。在了解为什么需要闭包之前,需要先看看javascript特殊的变量作用域。
javascript可以在函数内部读取全局变量!
var a = 1;
function test()
{
a = 3;
alert(a);
}
test();
输出结果是3,这在c++里是完全不能理解的,全局变量你函数怎么访问到的?
回味一下c++的处理方式,局部变量,参数变量存放在栈中,当离开作用范围后,分配的内存在作用范围外会被系统自动回收。new出来的内存空间存放在堆中,不受作用域管理,不会被系统自动回收,只有在使用delete删除或者整个程序结束后才会释放内存。
记住这个后,为什么需要闭包就呼之欲出了,如果我们需要只在函数内部访问的变量,那就再嵌套一层呗,把当前函数当作全局,那往下的一层函数不久可以访问当前函数的变量了吗?(套娃?)
function test()
{
var a = 3;
function taowan()
{
alert(a);
}
return taowan;//返回套娃
}
var t = test(); //接收套娃
t(); //输出3
这个套娃把上一层套娃的记忆(变量a)带出来了,也就是说,虽然外面的壳没了,但是变量a却永远存在了它的心中。
闭包的定义是:在函数中使用的未在函数中定义的但在函数所处上下文有效的变量(标识符)与函数本体的集合。闭包允许函数附带变量,形成自己的一片天地,有点像面向对象中对象的一个属性附带的方法。下面举几个例子说明闭包的强大作用。此例来自火狐开发者网站https://developer.mozilla.org
var makeCounter = function() {
var privateCounter = 0; //私有
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
}
};
var Counter1 = makeCounter();
var Counter2 = makeCounter();
console.log(Counter1.value()); /* logs 0 */
Counter1.increment();
Counter1.increment();
console.log(Counter1.value()); /* logs 2 */
Counter1.decrement();
console.log(Counter1.value()); /* logs 1 */
console.log(Counter2.value()); /* logs 0 */
该共享环境创建于一个立即执行的匿名函数体内。这个环境中包含两个私有项:名为 privateCounter
的变量和名为 changeBy
的函数。这两项都无法在这个匿名函数外部直接访问。必须通过匿名函数返回的三个公共函数访问。什么意思呢?就是闭包可以模拟私有方法,把函数做成接口,只有此对象才可以访问。
而且因为闭包可以储存变量,所以我们可以把两个变量的函数封装成只需要一个变量:
function make_pow(n) {
return function (x) {
return Math.pow(x, n);
}
}
// 创建两个新函数:
var pow2 = make_pow(2);
var pow3 = make_pow(3);
console.log(pow2(5)); // 25
console.log(pow3(7)); // 343
希望这篇文章能让你理解闭包,如果我对闭包有新的认识,还会加入进去的!
标签:mozilla 通过 结束 允许 特殊 javascrip 理解 对象 全局变量
原文地址:https://www.cnblogs.com/lyc1226/p/12109905.html