扫码关注官方订阅号
请教高手,广义而言,所有JS的函数都可以称为闭包,因为JS函数在创建时保存了当前的词法环境这句话怎么理解。
欢迎选择我的课程,让我们一起见证您的进步~~
js的执行环境本身就是一个scope(浏览器的window/node的global),我们通常称之为全局作用域。每个函数,不论多深,都可以认为是全局scope的子作用域,可以理解为闭包。
因为全局函数关联全局域(global scope),局部函数关联某个局部域(local scope),它们的形式是统一的。
另外,域和域有前后顺序但不直接关联,只有函数关联到创建位置的域([[scope]]),以及域关联到创建时被调用的函数(argument.callee)。这个链实际上就是调用链,它的终点就是全局域,解释器就在这个链上寻找变量。
[[scope]]
argument.callee
另外全局域也是相对的,并不是像编译成二进制之后那样是固定的一块地方,在解释器的层面上,或者作为模块被别的代码调用的时候,全局域不过是另一种局部域而已。
闭包的设计是为了要解决函數自變量問題(Funarg problem),闭包与自由变量的定义如下:
闭包是代码块和创建该代码块的上下文中数据的结合。 自由变量是指在函数中使用的,但既不是函数参数也不是函数的局部变量的变量。
闭包是代码块和创建该代码块的上下文中数据的结合。
自由变量是指在函数中使用的,但既不是函数参数也不是函数的局部变量的变量。
ECMAScript使用了几项技术的设计,其中之一是作用域链来解决这个问题,在所有的函数中都有一个[[Scope]]物件来保存变量对象,其中也包含了全域对象,按照作用域链与[[Scope]]的设计,函数在最后执行会依包含其中的变量来执行。
因为ECMAScript并没有明确的规范当函数如果不需要引用自由变量时,是否需要把上层的作用域链也保存在[[Scope]]之中,所以在理论上会认为所有的函数都是有同样的设计。
[[Scope]]是一个包含了所有上层变量对象的分层链,它属于当前函数上下文,并在函数创建的时候,保存在函数中。
因此,在理论上认为所有的函数在创建时,就会把上层的作用域键也保存住,即使是最外层的全域也是。所以所有的函数都认为是一个闭包。
但从实践角度:以下函数才算是闭包:
即使创建它的上下文已经销毁,它仍然存在(比如,内部函数从父函数中返回)
在代码中引用了自由变量
以上内容均参考自: http://goddyzhao.tumblr.com/p...与http://goddyzhao.tumblr.com/p...。中文的需要深入自行参考。
因为Javascript的作用域链的原因,参考Scope,函数内的变量的作用域会延伸到在该函数内定义的函数里,这样,子函数就符合了闭包的定义,所以每个函数都是闭包。
看看阮大神写的这篇文章学习Javascript闭包(Closure)
小结一下,因为任何JS函数都可以通过链式作用域访问到外部环境的变量,同时任何函数都不可能超出全局环境,所以可视为每个函数都保存了外部的环境,这符合了闭包的概念。
闭包不闭包的 不就是起个名字吓吓人吗 跟所谓AOP一样 有啥意义
哈哈,记得之前有个人问了一个闭包的问题,我就说了一句所有函数都是闭包,然后就被各种踩,最后直接把我的回答给删了,真是服了,宝宝心里苦呀。
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
js的执行环境本身就是一个scope(浏览器的window/node的global),我们通常称之为全局作用域。每个函数,不论多深,都可以认为是全局scope的子作用域,可以理解为闭包。
因为全局函数关联全局域(global scope),局部函数关联某个局部域(local scope),它们的形式是统一的。
另外,域和域有前后顺序但不直接关联,只有函数关联到创建位置的域(
[[scope]]),以及域关联到创建时被调用的函数(argument.callee)。这个链实际上就是调用链,它的终点就是全局域,解释器就在这个链上寻找变量。另外全局域也是相对的,并不是像编译成二进制之后那样是固定的一块地方,在解释器的层面上,或者作为模块被别的代码调用的时候,全局域不过是另一种局部域而已。
闭包的设计是为了要解决函數自變量問題(Funarg problem),闭包与自由变量的定义如下:
ECMAScript使用了几项技术的设计,其中之一是作用域链来解决这个问题,在所有的函数中都有一个[[Scope]]物件来保存变量对象,其中也包含了全域对象,按照作用域链与[[Scope]]的设计,函数在最后执行会依包含其中的变量来执行。
因为ECMAScript并没有明确的规范当函数如果不需要引用自由变量时,是否需要把上层的作用域链也保存在[[Scope]]之中,所以在理论上会认为所有的函数都是有同样的设计。
因此,在理论上认为所有的函数在创建时,就会把上层的作用域键也保存住,即使是最外层的全域也是。所以所有的函数都认为是一个闭包。
但从实践角度:以下函数才算是闭包:
即使创建它的上下文已经销毁,它仍然存在(比如,内部函数从父函数中返回)
在代码中引用了自由变量
以上内容均参考自: http://goddyzhao.tumblr.com/p...与http://goddyzhao.tumblr.com/p...。中文的需要深入自行参考。
因为Javascript的作用域链的原因,参考Scope,函数内的变量的作用域会延伸到在该函数内定义的函数里,这样,子函数就符合了闭包的定义,所以每个函数都是闭包。
看看阮大神写的这篇文章学习Javascript闭包(Closure)
小结一下,因为任何JS函数都可以通过链式作用域访问到外部环境的变量,同时任何函数都不可能超出全局环境,所以可视为每个函数都保存了外部的环境,这符合了闭包的概念。
闭包不闭包的 不就是起个名字吓吓人吗 跟所谓AOP一样 有啥意义
哈哈,记得之前有个人问了一个闭包的问题,我就说了一句所有函数都是闭包,然后就被各种踩,最后直接把我的回答给删了,真是服了,宝宝心里苦呀。