javascriptb闭包的问题

直观地理解Javascript closure的本质 ..

■网友
谢邀。
【javascriptb闭包的问题】 确实两种方式通过将return语句都可以在词法作用域外部访问到局部变量和方法,但是这只是闭包的其中一个特点..
闭包的特点如下
基于词法作用域的查找规则。如果在f2自身的词法作用域中存在变量n,则会返回;否则会想上查找,直到全局作用域。如果仍然找不到变量n,会报RefferenceError的错误。这个特点也就是题主所说的特点将内部函数作为值返回或者立即执行该函数或者将函数作为参数传递到另一个函数中拥有更长的生名周期,能够记住所在的词法作用域看看最后一个特点
let func = () =\u0026gt; {\tlet num = 10;\tlet inner = (param) =\u0026gt; {\t\treturn num += param;\t}\treturn inner;}let f2 = func();console.log(f2(10));\t// 20console.log(f2(10));\t// 30// num值进行累加,而不是重置,这就是体现了闭包的最后一个特点当然,使用闭包可以做出很多事情,如单例模式减少全局变量污染,同时对外提供API接口等
关于闭包的其他知识点可以看看以下回答
什么是闭包?js关于for循环中的闭包问题? - 【javascript闭包】一段简单的代码,关于累加?关于Javascript闭包的经典面试题,还是不明白原理,求教?
■网友
黑人脸
你的方法是通过return返回了一个值,确实可行,那万一要返回多个基本类型的值呢(别说用数组返回阿,你给我返回多个数组试试...一样的道理)。
闭包它由于对外部函数的活动对象的引用,对该活动对象内部的变量进行相关的操作,直到闭包销毁之前,该活动对象一直存在(即变量一直存在)。
function f1(){\tvar x = 1;\tvar str = "hello";\treturn function f2(){\t\tx++;\t\tstr += " world!";\t\talert(x);\t\talert(str);\t}}var f2 = f1();f2();闭包就是将函数内部和函数外部连接起来的一座桥梁。
这句话仅仅代表了连接函数内部和外部,并不是说不能通过其它方式去获取函数内部变量的值,你所用的return也是其中一种方式。
至于为什么能连接函数内部和外部(如果懂了可以自行忽略哈)
作用域可以分为两种,全局作用域和局部作用域。
一个函数内部便是一个局部作用域。
当我们“创建”一个函数的时候,同时系统就为我们创建了相对应的作用域链,此时的作用域链仅仅包含全局作用域
但是当我们“执行”一个函数的时候,系统不仅会创建该函数的作用域,还复制了创建函数时的作用域链,此时的作用域链包含了该函数的作用域、全局作用域
而闭包是镶嵌在函数内部的函数。
外部函数是一个局部作用域,闭包又是一个局部作用域,那么这时候的作用域链为
最内层(闭包)作用域=\u0026gt;外部函数作用域=\u0026gt;全局作用域
这也造成了作用域链的变量搜索机制:当我们想要搜索一个变量时,会先在最内层函数的活动对象中去寻找是否有该变量,如果没有再去找外部函数作用域,一直到全局作用域,找到则返回,找不到则抛出ReferenceError异常。
此时你一定在纠结,明明我外部函数都执行完毕了,那么变量也不应该存在了,为什么还能在闭包中还能调用这个变量。
function f1(){\tvar x = 1;\treturn function f2(){\t\tx++;\t}}var f2 = f1();当外部函数执行完,它的执行环境上下文和作用域链也会销毁,但是它的活动对象由于闭包引用着,所以活动对象并没有销毁,也就是为什么变量x没有被销毁的原因。
如果还不理解可以看下面的代码
var obj = {\t"name" : "suoz"};var other_Obj = obj;obj = null;alert(obj);\t\t//nullalert(other_Obj);\t//


推荐阅读