《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是[color=blue]被执行的代码[/color]和[color=blue]这些代码被执行时所在的作用域[/color]的结合。这种代码和作用域的结合在计算机科学文献中被称作闭包。所有的JS函数都是闭包。

这与印象中闭包差别挺大,尤其是最后1句。

var values=(function(){
var id=0;
return function(){
return id++;
}
})();

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

<script>
var s=0;
function test1(){//当前作用域链被保存
alert(s);
}
function test2(){
var s=1;
test1();//定义它时所保存的作用域链被使用
}
test2();
//0==>词法作用域;1==>动态作用域。
</script>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值