神马叫“闭包”???

本文参考博客:
1. http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

    2.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures (官方的)

第一步:理解链式作用域

答:Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。 不同于块级作用域哦!

function f1(){
    var n=999;
    function f2(){
      alert(n); // 999
    }
  }

如上,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。这就是Javascript语言特有的"链式作用域"结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

第二: 对于阮老师博客的理解补充

阮老师在闭包博客中说:它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

第一点是认同的,但第二点有点不敢苟同(初生牛犊,如有错误,还请大神留言指教)。

阮老师的js代码:

function f1(){
    var n=999;
    nAdd=function(){n+=1} // 全局变量
    function f2(){ // 局部变量
      alert(n);
    }
    return f2;
  }

var result=f1(); // 因为这里改变了f2的作用域,所以f2才一直在内存中。 作用域由(f1()内部变量 ——》f1()平级)。

result(); // 999

nAdd(); // 由结果看,下面的值为1000,说明nAdd() 执行了, 因为f2作用域被改变后就一直在内存中,所以f1也一直在内存中。

result(); // 1000

// 我如果这样写,换一种方式调用,不改变f2的作用域

  f1()(); // 999     执行完毕,f2的内存空间被销毁。 f1的内存空间也被销毁,nAdd虽然是全局变量,但其是方法的属性,自然也被销毁。

  nAdd();             // undefined     

  f1()();              // 还是999

由上面我们可以提出几点疑问:

1.注意变量的访问范围和生命周期
2.方法内部的全局变量会随着方法的销毁而销毁。 注意变量的访问范围和生命周期!
3.第二种调用方式:立即执行函数。

一句话总结:
1.闭包就是能够读取其他函数内部变量的函数(是其他函数的内部函数)。
2.定义在一个函数内部的函数"。

3.闭包就是将函数内部和函数外部连接起来的一座桥梁。

4.由于js其特殊的作用域规则,要通过外部来访问函数的内部变量。 ——————闭包就是干这个的!

补充

代码理解:

function f1(){
var n=999;
nAdd=function(){n+=1;return n;} // 全局变量:都可以调用,前提是创建了-----销毁之前外部可以访问。
function f2(){
alert(n);
}
return f2;
}
alert(f1()); // 调用f1,返回f2 不调用f1都不会创建nAdd
alert(nAdd());

你可能感兴趣的:(神马叫“闭包”???)