《JavaScript The Definitive Guide 5th》闭包读后总结

JavaScript functions are a combination of code to be executed and the scope in which to execute them. This combination of code and scope is known as a closure in the computer science literature.All JavaScript functions are closures.

   JS是 被执行的代码这些代码被执行时所在的作用域的结合。这种代码和作用域的结合在计算机科学文献中被称作闭包。所有的JS函数都是闭包。

这与印象中闭包差别挺大,尤其是最后1句。
var values=(function(){
  var id=0;
  return function(){
     return id++;
  }
})();

    按我的理解,这只是对闭包的一种特殊形式的应用(外部引用指向内嵌函数,使得嵌套函数的call object继续存在),但不能说明只有这个才叫做闭包。闭包是所有JS函数的固有状态。
     Lexical Scoping(词法作用域,也称静态作用域)、scope chain(作用域链)、call object(调用对象)很关键、很有难度,它们是闭包的根本。
     介绍如下:
     scope chain
     由一组按次序排列的对象组成的对象,函数查找变量时,首先选择其中的第一个对象,如果该对象中没有,则选择下一个对象,以此类推。
     Lexical Scoping:
    定义函数时,当前的作用域链便被保存到函数的内部变量中;函数被调用时,启用的就是这个被保存的作用域链,而不是根据执行环境动态地创建。
<script>
var s=0;
function test1(){//当前作用域链被保存
   alert(s);
}
function test2(){
   var s=1;
   test1();//定义它时所保存的作用域链被使用
}
test2();
//0==>词法作用域;1==>动态作用域。
</script>

    所以会这样描述词法作用域的功能:函数在定义的它的作用域中执行,而不是执行它的作用域。
   调用对象
  调用函数时,首先执行上述动作。然后创建call object(调用对象),将其加入作用域链最前端,也就是函数查找变量时,优先选择该对象。调用对象使用属性arguments进行初始化,该属性指向该函数的Arguments对象。所有命名参数(函数参数列表中的参数)因此都被加入调用对象里。所有以var声明的局部变量也都在该对象中 被定义
    词法作用域与作用域链的关系:前者用来决定函数如何选择作用域链。
    作用域链与调用对象的关系:调用函数时,作用域链由定义该函数的作用域链+该函数的调用对象组成。
    但定义函数时,作用域链如何构成不清楚:假如存在函数嵌套,定义被嵌套函数的作用域链必然包括外层函数的作用域;外层函数在调用时,作用域链肯定包含其自身的调用对象;但定义被嵌套函数时,外层函数并没有被调用,也就是不存在调用对象,而此时,被嵌套函数又可以访问外层函数的一切参数、变量,那到底是什么使它拥有这种功能?这个矛盾现在无法解释。
   

你可能感兴趣的:(JavaScript)