资讯专栏INFORMATION COLUMN

javascript闭包不完全探索记录02:闭包?干嘛使!

Render / 3339人阅读

摘要:温馨提示作者的爬坑记录,对你等大神完全没有价值,别在我这浪费生命温馨提示续本文将会成为一篇笔记类型的文章,记录闭包具体的应用方式温馨提示再续本文存在错误,会慢慢改进的,请不要把我说的当真在上一篇博文闭包不完全探索记录闭包啥馅的中,对中

温馨提示:作者的爬坑记录,对你等大神完全没有价值,别在我这浪费生命
温馨提示-续:本文(maybe)将会成为一篇笔记类型的文章,记录闭包具体的应用方式
温馨提示-再续:本文(maybe)存在错误,会慢慢改进的,请不要把我说的当真

在上一篇博文 javascript闭包不完全探索记录01:闭包?啥馅的?- lskrat 中,对javascript中闭包本身进行了研究和学习,并取得了一定的成果(知道了老王私房钱藏哪了)

接下来,按照面试官的思路,他不会问你一个没有用的东西啊,闭包既然被广泛的提及则必然(maybe)有其存在的价值和意义。

所以我不禁产生了疑问,这货到底干啥的?闭包要是如此重要,为啥我能够在不理解的情况下就干了这么多前端开发?

下面就(逐渐)慢慢列出来吧

获取函数内部属性

在上文提到的博文中已经有所提及,因为javascript本身的作用域链特性,外部无法调用内部的属性,所以当我们希望调用一个内部变量的时候(也不知道是什么时候)可以利用闭包来建立外部与函数内部的联系,举个例子

function testClosure(){
    var innerInfo = "lskrat"
    return function(){
        return innerInfo
    }
}
console.log(testClosure()())//lskrat

通过在外部调用testClosure的返回函数,成功的get到了他的内部属性

保持变量的保存在缓存中

这要从一个经典的误会说起

    function testClosure(){
        var funcs = [];
        for(var i = 0 ; i < 5 ; i++){
            funcs[i] = function(){
                return i
            }
        }
        return funcs
    }
    console.log(testClosure()[0]())//5
    console.log(testClosure()[1]())//5

乍看之下,可能会觉得上面的运行结果有问题,按照上文代码的大概含义应该的到的结果应该是根据调取不同的返回函数得到不同的i值才对,可最终得到的都是5,显然事情不是这么简单的

我们来对console.log(testClosure()[0]())进行分析,看看这句话都干了什么,首先调用了testClosure()这个函数,函数内部的for循环开始工作,生成了一个由函数组成的数组funcs,这一步结束之后,for循环中的i就已经是5了,而且由于返回的funcs中调用了内部变量i,所以i=5就一直被存在了缓存之中没有被释放,此时再执行testClosure()[0]相当于调用了funcs[0],不过无论调用的是funcs中的哪一个函数,其实都是要返回i的值,而func[n]中的i并没有在循环中被直接赋予循环时i对应的值,而只是一个变量的引用,这个引用就是那个被存在缓存之中的5,所以最后的结果就都是5了。

那我们怎样才能让这个代码正常(按照我们的想法)呢?
上面的写法之所以结果都是5主要是因为在构建函数func[n]的时候,所指向的i的值并没有存在于一个闭包中,所以如果我们写一个闭包呢,写一个内部函数,调用i,将它的值封在一个闭包中,具体写法如下

    function testClosure(){
        var func = []
        function testInner(j){
            func[j] = function(){
                return j
            }
        }
        for(var i = 0 ; i < 5 ; i++){
            testInner(i)
        }
        return func
    }

    console.log(testClosure()[4]());//4
    console.log(testClosure()[2]());//2

为什么可以了?原因就在与这里出现的testInner函数提供了一个新的作用域及变量,在执行的过程中,每当生成一个func[n]与之对应的j都会因为作用域链的原因,连同其对应的值被“锁住”与func[n]一起形成闭包,所以其中对应的i值就被保留了下来

之前没用过很可能是我一直都在使用各种已经被各位大神封装的很好的js库了吧,从JQuery到Vue我欠原生js一个闭包

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

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

相关文章

  • javascript闭包完全探索记录01:闭包?啥馅的?

    摘要:闭包一词来源于以下两者的结合要执行的代码块由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放和为自由变量提供绑定的计算环境作用域。在以及及以上等语言中都能找到对闭包不同程度的支持。 温馨提示:作者的爬坑记录,对你等大神完全没有价值,别在我这浪费生命 闭包,好吃吗 ? 第一次听到这个词,很不幸是在一次面试中,可想而知结果很细碎,从此闭包和跨域在我匮乏的前端知识中成为了...

    TANKING 评论0 收藏0
  • javascript对象完全探索记录01:this! which?

    温馨提示:作者的爬坑记录,对你等大神完全没有价值,别在我这浪费生命 这一切,源于阮大神博文学习Javascript闭包(Closure)- 阮一峰中的一道思考题 //问题1: var name = The Window; var object = {   name : My Object,   getNameFunc : function(){     return function(){    ...

    rubyshen 评论0 收藏0
  • JavaScript 是如何工作的:模块的构建以及对应的打包工具

    摘要:挂机科了次使用这个结构,匿名函数就有了自己的执行环境或闭包,然后我们立即执行。注意,匿名函数的圆括号是必需的,因为以关键字开头的语句通常被认为是函数声明请记住,中不能使用未命名的函数声明。 这是专门探索 JavaScript 及其所构建的组件的系列文章的第 20 篇。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 如果你错过了前面的章节,可以在这里找到它们: ...

    hedzr 评论0 收藏0
  • 讲清楚之javascript作用域

    摘要:并且作用域链也确定了在当前上下文中查找标识符后返回的值。为了具象化分析问题,我们可以假设作用域链是一个数组,数组成员有一系列变量对象组成。注意,所有作用域链的最末端都为全局变量对象。所以作用域作用域链都是在当前运行环境内代码执行前就确定了。 什么是作用域(Scope)? 作用域产生于程序源代码中定义变量的区域,在程序编码阶段就确定了。javascript 中分为全局作用域(Global...

    whidy 评论0 收藏0

发表评论

0条评论

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