闭包

闭包

闭包是个 js 中比较重要的一个概念了,面试前端或者 Node.js 方面的工作几乎95%以上的面试官都会问这方面的问题。但是对初学者来说,闭包是个特别抽象的概念,特别是 ECMAScript 给出的定义:

闭包是函数和声明该函数的词法环境的组合

如果你只是个小白没有实战经验,这句话你懂几个字?

先来看个函数

function init() {
    var name = "nys"; 
    // name 是一个被 init 创建的局部变量
    function displayName() { 
        // displayName() 是内部函数,一个闭包
        alert(name); 
        // 使用了父函数中声明的变量
    }
    displayName();
}
init();

init() 创建了一个局部变量 name 和一个名为 displayName() 的函数。displayName() 是定义在 init() 里的内部函数,仅在该函数体内可用。displayName() 内没有自己的局部变量,然而它可以访问到外部函数的变量,所以 displayName() 可以使用父函数 init() 中声明的变量 name 。但是,如果有同名变量 name 在 displayName() 中被定义,则会使用 displayName() 中定义的 name 。

再看个函数

function makeFunc() {
    var name = "nys";
    return function displayName() {
        alert(name);
    }
}
var myFunc = makeFunc();
myFunc();

从运行的结果来看,没有什么不一样,都是会输出 name 的值。但是内部的区别就在于,displayName() 函数在执行前先被返回了,先被返回到了定义的 myFunc 后,再用 myFunc()执行。在很多的编程语言中,函数内部的变量只能在函数执行期间被使用,一旦 makeFunc() 执行完毕,我们会认为 name 变量将不能被访问。然而,因为代码运行得没问题,所以很显然在 JavaScript 中并不是这样的。

其实,这就是 闭包 ,由函数以及创建该函数的词法环境组合而成。这个环境包含了这个闭包创建时所能访问的所有局部变量。在我们的例子中,myFunc() 是执行 makeFunc() 时创建的 displayName() 函数实例的引用,而 displayName() 实例仍可访问其词法作用域中的变量,即可以访问到 name 。由此,当 myFunc() 被调用时,name 仍可被访问,其值 nys 就被传递到alert 中。

闭包的用处

在很多的编程语言中,都支持将方法、字段等设置为私有,即把它们当作一个类的内部内容所调用,其调用权限仅限于本类。而 JavaScript 没有这种原生支持,但我们可以使用闭包来模拟私有方法。(也被成为模块模式)

var Counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }   
})();

console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */

在匿名函数 Counter()内只有一个共享的变量 privateCounter ,但是它被内部的三个函数所共享Counter.incrementCounter.decrementCounter.value。三个函数的操作都同时影响唯一变量 privateCounter

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值