关于js闭包的误区

 2023-09-11 阅读 22 评论 0

摘要:一直以为js的闭包只是内部函数保存了一份外部函数的变量值副本,但是以下代码打破了我的认识: function createFunctions() {var result = new Array();for(var i=0;i<10;++i){result[i] = function(){return i;}}return result; }var fu

一直以为js的闭包只是内部函数保存了一份外部函数的变量值副本,但是以下代码打破了我的认识:

function createFunctions()
{var result = new Array();for(var i=0;i<10;++i){result[i] = function(){return i;}}return result;
}var funcs = createFunctions();
for(var i=0;i<10;++i)
{console.log(funcs[i]());
}

  执行结果是10个10 而不是0-9

看了JS高级编程7.2.1之后才明白 变量i并不是存在于匿名函数的局部变量表,而是存储在createFunctions的活动对象表(存储参数和局部变量)中。并且在创建函数的定义过程中匿名函数只是被定义而没有被执行。直到后面输出的循环被定义的匿名函数们才得以执行,而这时候它们的活动对象表里并不存在i,然后它们就会从作用域链向上查找createFunctions的活动对象表中的i。这时i的值已经是10,因此它们的执行结果全是10。

以下代码在闭包外部再加入了一个含参数的闭包,并且在定义之后调用,传递进去当前的i。这时这层新增的闭包活动对象表中含有参数num会存储i的当前值。这样结果就是0-9了:

 1 function createFunctions()
 2 {
 3     var result = new Array();
 4 
 5     for(var i=0;i<10;++i)
 6     {
 7         result[i] = function(num)
 8         {
 9             return function(){
10                 return num;
11             }
12         }(i);
13     }
14     return result;
15 }
16 
17 var funcs = createFunctions();
18 for(var i=0;i<10;++i)
19 {
20     console.log(funcs[i]());
21 }

闭包的活动对象表中并不会包含this,this是当前执行上下文中的概念,会随着调用环境而变化。

js闭包是什么意思。 

 1 name = "global name"
 2 var obj = {
 3     name:"object name",
 4     func:function()
 5     {
 6         return function(){
 7              return this.name;
 8         }
 9     }
10 }
11 console.log(obj.func()());
12 
13 var obj2 = {
14     name:"object name",
15     func:function()
16     {
17         that = this;
18         return function(){
19              return that.name;
20         }
21     }
22 }
23 console.log(obj2.func()());
24 
25 var obj3 = {
26     name:"object name",
27     func:function()
28     {
29         return this.name;
30     }
31 }
32 console.log(obj3.func());
33 console.log((obj3.func)());
34 console.log((obj3.func = obj3.func)());

输出结果:

global name
object name
object name
object name
global name

第一个输出 因为this并不在活动对象表里,闭包在调用的地方才获得当前的this,也就是全局对象

第二个输出 因为闭包定义之前取了this存到外层函数的that变量,用that就可以得到自定义对象

第3,4个输出 没有闭包 直接输出this

js什么时候会用到闭包、第五个输出 因为赋值表达式取结果的操作把当前的上下文变成了全局的,可以当做赋值操作不属于任何对象因此得到的是全局对象

转载于:https://www.cnblogs.com/fancybit/p/js_closeture_mistake.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/3/45325.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息