javascript的闭包

Posted lyc1226

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript的闭包相关的知识,希望对你有一定的参考价值。

闭包

为什么需要闭包

闭包是一个比较容易搞混的地方,不知道闭包是干嘛的就强行学习,结果只能学个不明不白。在了解为什么需要闭包之前,需要先看看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

希望这篇文章能让你理解闭包,如果我对闭包有新的认识,还会加入进去的!

以上是关于javascript的闭包的主要内容,如果未能解决你的问题,请参考以下文章

Spark闭包与序列化

JavaScript ---- 闭包(什么是闭包,为什么使用闭包,闭包的作用)

JavaScript 闭包(随笔)

javascript中的闭包

Javascript中的闭包

Javascript中的闭包(转载)