【great】js函数闭包学习贴

前几天看了《javascript语言精髓与编程实践》对函数闭包的讲解,很有感触,跟大家分享一下。



  其实js支持函数闭包的主要原因是因为js需要函数能够保存数据。这里的 保存数据 是指函数在运行结束以后函数内变量的值也会进行保存。至于为什么js需要在函数内可以保存数据,那就是js是一种函数式语言。在函数内保存数据是函数式语言的一大特征。上代码:
JScript code
   
   
var getValue,setValue; function test(){ var value = 100 ; getValue = function (){ return value; } setValue = function (x){ value = x; } } test(); alert(getValue()); // 输出100 setValue( 200 ); // 设置value alert(getValue()); // 输出200


上例表明函数内部可以保存数据,而这是通过函数闭包实现的。



函数闭包是一个 运行时的概念。函数闭包对应函数实例。而一个函数定义可能会对应多个函数实例。那么在什么情况下会返回不同的函数实例呢?

JScript code
   
   
function getFunction(){ return function (){ alert(value); } } var func1 = getFunction(); var func2 = getFunction(); alert(func1 == func2) // 输出false,表示是两个不同的函数应用。


很多情况下使用的都是不同的函数实例。比如在使用函数作为构造函数时。其实在不同情况下返回不同的函数实例也是可以解释的。后面我们会说到。



每一个函数实例对应至少一个函数闭包。对应一个闭包居多。故先说明对应一个函数闭包。

基本一个函数运行一次就会建立函数闭包。

闭包的实现其实很类似于js对象的实现。函数闭包建立时会将函数内声明的变量登记进一个表中。当函数内存取值时就会查阅此表,表中没有相关变量时就会去父类的闭包中寻找,直至最上层闭包,即最外层所在的闭包。

JScript code
   
   
var value = 1 function test(){ var value = 7 ; function inline(){ var value = 4 ; alert(value); } inline(); } test(); // 输出4

上面总共有三个闭包。一个全局闭包,该闭包中仅登记了一个变量value。test实例一个闭包,该闭包中也登记了一个value变量。inline实例一个闭包,该闭包同样也是只登记了一个value变量。三个闭包间的关系:全局闭包是test实例闭包的父闭包,test实例闭包是inline实例闭包的父闭包。所以输出4。

稍加修改
JScript code
   
   
var value = 1 ; function test(){ function inline(){ alert(value); } } test(); // 输出1

以上面的说明同样是可以解释的。上面的说明同样可以解释js函数中的一个规定。 当在函数内不用var声明变量时,该变量被认为是全局变量。因为不使用var,函数内部先在自己的闭包内寻找变量,直至最上层闭包也没有寻找到,故在最上层(全局)声明该变量。
闭包的生存周期:当前闭包内没有任何值被应用,该闭包即销毁。

JScript code
   
   
var getFunc; function test(){ var func = function (){ alert(‘ new function ’); } getFunc = function (){ return func; } } test(); var func1 = getFunc(); var func2 = getFunc(); alert(func1 == func2) // 输出true

上例中运行test,为test函数实例建立闭包。并对全局变量getFunc赋值。 因为getFunc中含有对test实例函数闭包func的引用, 所以该闭包不会被销毁,所以返回的总是同一个函数func的引用。还有一个更为典型的例子:
JScript code
   
   
var checkre; function myFunc(){ if (checker){ checker(); } alert(‘myFunc:’ + str); var str = ’ test’; if ( ! checker){ checker = function (){ alert(‘checker:’ + str); } } return arguemnts.callee; // 返回当前运行函数的引用 } myFunc()(); // myFunc连续运行两次。

结果是

myFunc :undefined

checker: test

myFunc:undefined

上面提到函数每()运行一次,就会建立一个函数闭包。故上例总共为myFunc先后建立了两个函数闭包。第一个函数运行结束后,输出结果第一行,checker被赋值,str登记在此闭包中,因为checker引用str,故第一个函数闭包不会销毁。当函数第二次运行时,checker有值,故运行,但是checker内引用的是第一个闭包内的str=‘test’,故会输出第二行的内容。然后myFunc输出结果第三行,因为此时str引用的当前闭包内的str,故为undefined。

最上面的getFunction的例子。每次都返回一个函数实例,是因为每次都建立一个闭包。

运行时存在函数闭包链,提供对函数外定义的变量的访问。
第一次写,有点散,希望对大家有帮助。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript中的闭包是指一个函数能够访问并使用其外部作用域中的变量,即使在该函数被调用之后,该外部作用域的上下文已经销毁。简单来说,闭包是指一个函数保留了对其词法作用域的引用,使得函数可以访问和操作外部作用域的变量。 在JavaScript中,闭包可以通过函数嵌套来创建。当一个函数在内部定义了另一个函数,并且内部函数引用了外部函数的变量,那么内部函数就形成了闭包闭包函数可以访问和修改外部函数的变量,即使在外部函数执行完毕后,这些变量依然存在于闭包函数的作用域中。 以下是一个闭包函数的例子: ```javascript function outerFunction() { var outerVariable = 'Hello'; function innerFunction() { console.log(outerVariable); } return innerFunction; } var closure = outerFunction(); closure(); // 输出 'Hello' ``` 在这个例子中,内部函数`innerFunction`形成了闭包,它可以访问和使用外部函数`outerFunction`中的变量`outerVariable`,即使`outerFunction`执行完毕后,闭包仍然可以访问和操作`outerVariable`的值。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [JavaScript中的闭包](https://blog.csdn.net/qq_44482048/article/details/128714553)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [轻松学习Javascript闭包函数](https://download.csdn.net/download/weixin_38628429/13018893)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [JavaScript闭包](https://blog.csdn.net/qq_57586976/article/details/127678306)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值