资讯专栏INFORMATION COLUMN

JavaScript之闭包与立即执行函数

Scorpion / 2246人阅读

摘要:闭包与立即执行函数前言最近在细读高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以用自己所理解的,尝试解读下。作用域链的这种配置机制引出了一个值得注意的副作用,即闭包只能取得包含任何变量的最后一个值。

闭包与立即执行函数

前言:最近在细读Javascript高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以用自己所理解的,尝试解读下。如有纰漏或错误,会非常感谢您的指出。文中绝大部分内容引用自《JavaScript高级程序设计第三版》。

作用域链的这种配置机制引出了一个值得注意的副作用,即闭包只能取得包含任何变量的最后一个值。

function createArray(){

    var result = new Array();

    for(var i = 0; i < 10; i++) {
        result[i] = function() {
            return i;
        }
    }

    return result;
}

这个函数会返回一个函数数组。表面上看,似乎每个函数都应该返回自己的索引值,即位置0的函数返回0,位置1的函数返回1, 以此类推。

但实际上,每个函数都返回10,因为每个函数的作用域中都保存着createArray的活动对象,所以他们引用的都是同一个变量i。

当createArray()函数返回后,变量i的值是10,此时每个函数都引用着同一个变量i,所以i的值是10。

// 代码执行过程

createArray();

/*
createArray() {
    var result = new Array();

    var i; // 0,1,2,3,4,5,6,7,8,9,10

    for ( i = 0; i < 10 ; i ++) {
        result[i] = function() {
            return i; 
            // 注意 函数的执行时机,你只有调用函数的时候,才会产生执行环境,沿着作用域链,找到活动对象
            // 这里有个闭包,还记得闭包的概念吗? 有权访问到另外一个函数作用域的变量的函数
        }
    }
    
    /*
    result[0] = function(){
        return i
    }
    result[1] = function(){
        return i
    }
    result[2] = function(){
        return i
    }
    ....
    */
    return result;
}

result = [function(){return i}, function(){return i}....];

*/

createArray()[1](); // 10

那么如何让这个函数的行为符合我们的预期呢?

可以通过创建另一个匿名函数强制让闭包的行为符合预期,这里也应用了立即执行函数。

//立即执行函数
//我们平时写函数然后调用是这么写的。
//声明函数,调用执行。

function foo(){
    console.log("hi");
}

foo(); // "hi"

//那么,我们可不可以声明调用写一块呢? 这就是申明函数立刻执行。
//好像不可以,控制台报错

function foo(){
    console.log("hi");
}(); //Uncaught SyntaxError: Unexpected token )


//那么如果用括号包裹呢?

(function foo(){
    console.log("hi");
}()); // "hi", 可以了。 这就是立即执行函数! 

有了立即执行函数,就可以强制让闭包的行为符合我们的预期了。

//改写代码

function createArray() {

    var result = new Array();

    for( var i = 0; i < 10; i ++ ) {
        result[i] = (function(i) { 
            return function(){
                return i;
            }
        }(i));
    }

    return result;

}

createArray()[0](); // 0
createArray()[1](); // 1
createArray()[2](); // 2 

// 这里不只有一种方法,其他方法在此不表。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98782.html

相关文章

  • 进击的 JavaScript(五) 立即执行函数闭包

    摘要:匿名函数是不能单独写的,所以就提不上立即执行了。六立即执行函数在闭包中的应用立即执行函数能配合闭包保存状态。来看下上节内容中闭包的例子现在,我们来利用立即执行函数来简化它第一个匿名函数执行完毕后,返回了第二个匿名函数。 前面的闭包中,提到与闭包相似的立即执行函数,感觉两者还是比较容易弄混吧,严格来说(因为犀牛书和高程对闭包的定义不同),立即执行函数并不属于闭包,它不满足闭包的三个条件。...

    vincent_xyb 评论0 收藏0
  • JavaScript 立即执行函数闭包

    摘要:,立即执行函数就是定义后马上就执行的函数,用来隔绝作用域使无法在外部被访问,函数访问了函数外面的变量,这两者就形成了闭包与形成了闭包闭包 1,立即执行函数就是定义后马上就执行的函数,用来隔绝作用域使 _foo 无法在外部被访问 2,函数访问了函数外面的变量,这两者就形成了闭包get() 与 _foo 形成了闭包 (function() { var _foo = 1 window...

    Brenner 评论0 收藏0
  • 老生常谈闭包(你不可不知的若干知识点)

    摘要:闭包是什么这是一个在面试的过程中出现的概率为以上的问题,也是我们张口就来的问题。文章推荐我们面试中在被问到闭包这个问题是要注意的几点闭包的延伸,让面试变得 闭包是什么?这是一个在面试的过程中出现的概率为60%以上的问题,也是我们张口就来的问题。但是我们往往发现,在面试的过程中我们的回答并不那么让面试官满意,我们虽然能张口说出一些但是却不能系统的对这个问题进行回答。面试官希望加入自己团队...

    daydream 评论0 收藏0
  • JavaScript闭包(三)

    摘要:目录执行环境与作用域链立即执行函数闭包知识点什么是闭包使用闭包的意义与注意点闭包的具体应用小结这是基本语法的函数部分的第篇文章,主要讲述了中比较重要的知识点闭包在讲闭包之前,在上一篇函数二的基础上,进一步深化执行环境和作用域链的知识点,并补 目录 1.执行环境与作用域链 2. 立即执行函数 3. 闭包知识点 3.1 什么是闭包 3.2 使用闭包的意义与注意点 3.3 闭包的具体应用 4...

    Anonymous1 评论0 收藏0
  • 【进阶2-3期】JavaScript深入闭包面试题解

    摘要:闭包面试题解由于作用域链机制的影响,闭包只能取得内部函数的最后一个值,这引起的一个副作用就是如果内部函数在一个循环中,那么变量的值始终为最后一个值。 (关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导) 本周正式开始前端进阶的第二期,本周的主题是作用域闭包,今天是第8天。 本计划一共28期,每期重点攻克一个面试重难点,如果你还不了...

    alanoddsoff 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<