闭包

作者: 小漠穷秋 | 来源:发表于2017-11-15 21:02 被阅读0次

通过一些题目来理解闭包。

涉及知识点:
1.执行上下文
2.作用域链
3.this指针
4.垃圾回收机制:标记回收

例子1:
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'

例子2:
function foo() {
var a = 1;
function bar() {
a = a + 1;
alert(a);
}
return bar;}

var closure = foo(); // 这个时候返回的是 bar() 这个函数外加其包上的变量 a; 这里的a没有进行垃圾回收。
var closure2 = foo(); // 这里同样生成了另外一个闭包(实例)
closure(); // 2
closure2(); // 2 , 绑定了另外一份变量 a
closure(); // 3

例子3:
var a = 1;
function foo() {
function bar() {
a = a + 1;
alert(a);
}
return bar;
}
var closure = foo();
var closure2 = foo();
closure(); //2
closure2(); //3
closure(); //4

例子4:
var funcs = [];
for(var i=0; i < 5; i++) {
funcs[i] = function() { alert(i); }
}

for(var j=0; j < funcs.length; j++) {
funcsj;
}

例子5:
 var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;//this指针会时刻改变
      };
    }
  };
  alert(object.getNameFunc()());

例子6:

var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };
  alert(object.getNameFunc()());

闭包的作用:

它的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
总是要通过return进行实现,因为return才能进行function作用域的延续。
因此,全局变量通过null解除引用 局部变量在离开执行环境时自动解除引用。

文字解释:

JavaScript 中的闭包实现与 JavaScript 的 Scope Chain 是密不可分的. 首先在 JavaScript 的执行中会一直存在一个 Execute Context Stack 。 Execute Context Stack 中最下面一个一定是 GlobalContext, 而在每一个函数的执行开始就会向这个 stack 中压入一个此 Function 的 Execution Context; 而一个 Execution Context 的组成分为三部分:

  1. Variable Object: 存储方法内的变量 vars, 方法传入的参数, 函数内定义的函数等等(函数表达式不保存), Variable Object 在任何时候是不可以被直接访问到的, 当然不同的 JS 引擎提供了访问接口就说不定了;
  2. Scope Chain: 这个函数执行的时候用以寻找值的 Scope Chain, 这个 Scope Chain 由 Variable Object + All Parent Scopes 组成, Variable Object 会放在这个 Scope Chain 的最前面, 这也是为什么函数内的变量会被最先找到;
  3. thisValue, 函数被调用的时候的 this 对象, 存储的就是函数的调用者(caller)的引用; 对于 Variable Object 在不同的情况下会有不同的定义, 例如在全局的时候被称为 Global Object, 而在函数中则被称为 Activation Object 激活对象; 正是由于有了 Execution Context 中的 Scope Chain, JavaScript 才能够使得在方法 bar() 的内部访问到方法 foo() 中的变量 a, 才能够使方法 bar() 将变量 a 关闭在自己的作用范围内不让他随 foo() 方法的执行完毕而销毁;
    作用域链:


    image.png

参考文献:

https://segmentfault.com/a/1190000006185310

相关文章

  • swift-闭包

    闭包 闭包定义 闭包简化 - 尾随闭包 闭包参数 闭包返回值 闭包的循环引用

  • 闭包,闭包,闭包

    1、这家伙到底是什么? 网上关于这个的讨论的太多了太多了,有各种的举例子,但是大部分还在寻找这个答案的小伙伴对于变...

  • 闭包-Closures [swift 5.1]

    闭包的语法 尾随闭包 闭包逃离 自动闭包

  • Day7 闭包(Closures)

    本页包含内容:• 闭包表达式• 尾随闭包• 值捕获• 闭包是引用类型• 逃逸闭包• 自动闭包 1、闭包表达式 闭包...

  • Python闭包

    闭包 = 环境变量 + 函数 调用闭包内部的环境变量 闭包的经典误区 闭包与非闭包实现人类走路 非闭包 闭包

  • 闭包(closure)

    ● 闭包基础 ● 闭包作用 ● 闭包经典例子 ● 闭包应用 ● 闭包缺点 ● 参考资料 1、闭包基础 作用域和作...

  • swift- 闭包一

    /*• 闭包表达式• 尾随闭包• 值捕获• 闭包是引用类型• 逃逸闭包• 自动闭包*/

  • (9) python之闭包

    闭包闭包 = 函数 + 环境变量(函数定义的时候) 一个最简单的闭包 闭包不受外部变量影响 非闭包 闭包 闭包 只...

  • Swift-进阶 :闭包(二)逃逸闭包 & 非逃逸闭包

    本文主要分析逃逸闭包 、非逃逸闭包、自动闭包 逃逸闭包 & 非逃逸闭包 逃逸闭包定义 当闭包作为一个实际参数传递给...

  • javascript闭包详解

    跟我念 bi 闭 bao包 ,闭包的闭,闭包的包。。 闭包的简介 在计算机科学中,闭包(英语:Closure),又...

网友评论

      本文标题:闭包

      本文链接:https://www.haomeiwen.com/subject/yvepmxtx.html