您好、欢迎来到现金彩票网!
当前位置:老k棋牌 > 正闭包 >

阮一峰关于 Javascript 中闭包的解读是否正确?

发布时间:2019-06-27 05:43 来源:未知 编辑:admin

  阮一峰有一篇关于javascript 闭包的科普文章: 学习Javascript闭包(Closure) 感觉讲的挺好的,考虑到之前被朴灵喷的很惨,所以开始怀疑博文中的讲解是否正确。 博文部分观点: 1. 我的理解是,闭包就是能够读取其他函数内部变量的函数。 2.由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成定义在一个函数内部的函数。 3.闭包可以用在许多地方。它的最大用处有两个,一个是前面提到…

  函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!

  不使用 var 等於沒有聲明變量,而是相當於訪問了 window 的屬性。

  和在 window 下聲明變量的區別在於,訪問 window 的屬性創建的變量可以 delete,在全局作用域下直接聲明的變量不可以 delete。

  // ReferenceError: b is not defined

  // ReferenceError: c is not defined

  簡單明瞭,既指明了閉包的組成部分,又限定了範圍,比「其它函數」不知高到哪裏去了。

  由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成定义在一个函数内部的函数。

  即便在函數內部定義了函數,如果沒有引用父函數作用域的變量,也照樣可以不是閉包。

  爲了通俗而通俗,爲了容易理解而理解,只會使得讀者同樣流於表面,自以爲理解,實際上根本不懂。一旦難度稍微加大,舊有的思維不再好用,就難以提升了。

  反之一開始就接受抽象思維的訓練而不是套用舊有的思維,雖然一開始艱難,而後必會突飛猛進。

  建議樓主不要看任何低水平的「科普」文章,直接看英文維基百科、MDN、ECMAScript 草案比較好。

  真正的入門往往就是在一瞬間,過了這道坎,你就入門了。盲目地看再多低水平的文章,照樣毫無幫助。

  var a = function () { var test = {}; setTimeout(function () { console.log(test); }, 1000); }

  上面的例子中,test在a中定义,但在setTimeout的参数(函数)中对它保持了引用。当a被执行了,尽管a已经执行完(已经执行完),理论上来说a这个函数执行过程中产生的变量、对象都可以被销毁。但test由于被引用,所以不能随这个函数执行结束而被销毁,直到定时器里的函数被执行掉。

  var obj = function () { var a = ; return { set: function (val) { a = val; }, get: function () { return a; } } }; var b = obj(); b.set(new val); b.get();

  以上 obj这个函数在执行完之后理论上 函数体内东西都应该被回收掉。但它执行后的返回值 b 具有set和get方法。这两个方法里对a保持了引用,所以obj执行过程中产生的a就不会销毁。直到b先被回收,这个a才会回收。

  )的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。

  阮一峰的文章是他的学习笔记,并不保证全部正确,因为只是他的理解,而且这篇文章是他09年时写的,可能那时候他的水平比现在还差一些。

  不过他文章的含金量还是比较高的,同时因为是他的学习笔记,所以我们读起来也通俗易懂。很多初学者可以从阮一峰的文章向高水平进阶,但是通俗易懂的东西一般会存在不严谨的情况。严谨的文章非常好,但是不利于初学者理解。为什么这么说呢,严谨的概念会包含很多对初学者来说十分模糊的专业术语,比如上面答主cosx所提到的:閉包是由函式和與其相關的參照環境組合而成的實體。(原句可能是:A closure is an expression (typically a function) that can have free variables together with an environment that binds those variables (that closes the expression).)如果是初学者,我相信一看到函式、相关环境等字眼,则直接懵逼。

  但是阮一峰说:闭包就是能够读取其他函数内部变量的函数。这么解释,只要动动脑,应该可以大概理解闭包是什么东西了。即便这句话很不严谨。

  所以说阮一峰的文章依然值得看,他的文章可以把你带入一个领域,但是想要正确的认识这个领域,你依然需要去看书,这也是网络文章与实体书的区别。

  ----------------------------------------------

  想要彻底正确的理解闭包,还是要看cosx朴灵的回答,但是要攒够基础知识。

  Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。

  根本没有提到关键,为什么不能读取内部变量?函数在执行完后会销毁其内部环境这个就没提及。

  直接不解释this和运行时机制,这又是另一个可以写好几篇文章的知识点。初学者看这片文章是根本看不懂的,甚至会造成误解。

  强烈建议初学就要看口碑好的书,不要三三两两看博客,那些文章更多的是作者的备忘笔记而已,根本没办法教授你太多东西,甚至作者本身不求甚解。除非你本身就会,然后去看看,巩固加深印象。

  面新浪的时候,面试官说任何函数都是闭包,我觉得很对啊。阮一峰文中说,他的理解是‘闭包就是能够读取其他函数内部变量的函数’我觉得也很对啊。有些人觉得angular很渣,可是我用的时候很顺手,开发的时候就是很省事,我就觉得angular很棒。所以,只是看法而已,作用在那放着,就是调节作用域,随你怎么用,但是用的时候如果出错,那么肯定就不是闭包了。

  我上面的回答把作用域和闭包弄混了。不具有参考价值,感谢朴大大指出,受宠若精~~

  var b=function B(){ //执行到这一行定义了函数B,用表达式避免变量提升问题

  一个函数B在定义(声明)时,它在代码树上的上一层函数A此时正处于运行状态(执行上下文指向函数A),此时函数B会生成一个scope属性(函数本质也是对象,可以定义属性),B.scope是一个数组,但是通过代码是访问不到的,通过chome调试面板可以看到,留心的同学可以发现,push了A的活动对象(如果A有上一层函数,会依次push进去),此时B.scope=[{v1:1}],当前函数的活动对象包含了一个函数体内所有var声明的变量,在函数B内部查找变量时优先查找B的活动对象中的变量,如果没有,则遍历scope属性数组中的父级函数活动对象。

  因为只有在运行时的代码才能声明函数,每一个函数在声明时,父级函数必然处于执行状态,递归思考一下,可知作用域链完全由函数编写时的嵌套顺序所决定,这就是词法作用域的含义,看一个函数的作用域,只要静态分析代码树的结构就行了。

  所谓的作用域链,其实就是隐含的scope属性一级级的向上引用上一层函数的变量对象,变量对象的查找过程,原理上和对象的属性通过__proto__原型链查找过程差不多。

  闭包并不是什么新奇的概念,它早在高级语言开始发展的年代就产生了。闭包(Closure)是词法闭包(Lexical Closure)的简称。对闭包的具体定义有很多种说法,这些说法大体可以分为两类:

  这两种定义在某种意义上是对立的,一个认为闭包是函数,另一个认为闭包是函数和引用环境组成的整体。虽然有些咬文嚼字,但可以肯定第二种说法更确切。闭包只是在形式和表现上像函数,但实际上不是函数。函数是一些可执行的代码,这些代码在函数被定义后就确定了,不会在执行时发生变化,所以一个函数只有一个实例。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。所谓引用环境是指在程序执行中的某个点所有处于活跃状态的约束所组成的集合。其中的约束是指一个变量的名字和其所代表的对象之间的联系。那么为什么要把引用环境与函数组合起来呢?这主要是因为在支持嵌套作用域的语言中,有时不能简单直接地确定函数的引用环境。这样的语言一般具有这样的特性:

  函数是一阶值(First-class value),即函数可以作为另一个函数的返回值或参数,还可以作为一个变量的值。

  如果了解过JAVA,可以把闭包理解成为JAVA的类,闭包本身的方法理解成为类的构造函数,闭包返回的方法看作是类的成员方法,当然也可以理解成为一个JAVA的一个对象,或者一个类的实例。

  因为这个方法是与特定的数据绑定的,并且这个数据在外部还无法被访问,只能通过闭包返回的方法来进行特定的运算,所以就好像数据被包裹,封闭在了一个方法里面,闭包这两个字就是用来描述这种特性。

  闭包本身的特性使得它可以实现私有变量的功能,即变量只能内部访问而不能外部访问。

  闭包还可以实现类似面相对象里面类相似的特性,即同一个类的不同实例有着相同的方法,但因为自身的状态和数据不同,而方法会返回不同的结果。

  1&2:闭包是用来描述那个函数能够访问那个变量的这种能力的。而不是那个函数也不是那个变量。也就是一个函数能访问其词法范围之外的变量的能力。

  3:永久保存在内存?只是将对象的生命延长到和使用它的函数一致。如果所有使用它的函数都被回收了,这个变量也就回收了。(好吧,在实践中,这属于钻牛角尖了,而且还要看JS引擎如何实现)

  将额外参数传递给运行时生成的函数 (因为你生成的函数会被别人调用,比如回调函数,毫无疑问函数的参数个数和次序已定,但你的函数确实需要更多信息)

  一个变量进入闭包后,会被复制到堆中,所有对该变量的使用都解析为引用这个堆中的变量。所以,使用这个变量的所有函数都会读取到最新的值,而不是你创建该函数时的值。

  毕包的内部函数变量之所以可以访问循环中的每个操作痕迹,最重要的点就是函数参数承接了循环的每个值,而参数的一个重要作用就是让作用域局部无效化,简单来说就是内部函数访问父函数的参数不再只可以访问到最后一个值,而是每个值,这一点对于循环中序列号对应行为非常有用

  我觉得事实上闭包就是一块内存,在函数创建时就产生了,这块东西可以在开发者工具看到,除了location,global,还有一块就是他了。函数执行时可以读取这三块内存里面的东西,当然是有先后的。。

  ions/27719358/what-was-the-rationale-behind-having-the-receiver-in-functions-default-to-the-gl

http://thedailyjusa.com/zhengbibao/159.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有