Javascript中的闭包 O__O "…
Posted ✎_Vampire✟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javascript中的闭包 O__O "…相关的知识,希望对你有一定的参考价值。
一、闭包!?
闭包(closure)是javascript语言的一个难点,对于初学者来说不容易理解,那我们先来看看闭包的含义。
百度百科与“官方”解释:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
维基百科:在编程语言中,闭包(也称为词法闭包或函数闭包)是用于在具有第一类函数的语言中实现词法范围名称绑定的技术。
然而我们看到这些官方的解释并不能很清楚的了解闭包到底是什么鬼东西,只会一头问号,“你在说什么?”。
其实闭包简单来讲就是能够读取函数内部定义的局部变量的函数,而在Javascript中只有函数内部的子函数才能读取局部变量,所以我们也可以把闭包理解成定义在函数内部的函数。
二、函数的变量
想要理解闭包,我们就先要了解在函数中的变量,这些变量有自己的作用域。什么是作用域?呐,通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
变量的作用域有两种,一个是全局,一个是局部,也就是我们所说的全局变量和局部变量。
var a=50; function fun1(){ alert(a); } fun();
上面这段代码中,a在函数外面定义,所以在函数内部调用变量a自然可以读取它的值。这里的a我们就叫它全局变量。
function fun2(){ var a=50; } alert(a);
而在这段代码中,我们把a定义在函数内部,那么在函数外部调用a的时候,它会报错,告诉你“a is not defined”,我们找不到a啊?我们定义过a吗?当然定义过啊!只不过它是局部变量而已。
三、如何找到“藏”在函数里的变量
在我们敲键盘码代码的时候,总会有一些原因,需要我们得到函数内部的局部变量,那么“藏”在函数里的局部变量我们就需要用一种方法把他提取出来。
那就是在函数内部,我们再定义一个函数。
function fun3(){ var a=50; function fun4(){ return a; } return fun4(); }
//console.log(a); 报错 console.log(fun3());
在上面这段代码里,我们在fun3里面定义了一个变量a,这样我们在函数fun3外调用a同样会报错找不到它,而对于函数fun3内部的函数fun4来说,a是可以调用的,因外a在函数fun4的外部,反过来fun4内如果定义了一个变量那么fun3是不可调用的。
这里就又涉及到另一个概念,就是链式作用域,也就是我们说的作用域链。作用域链就是相同的变量名会产生作用域链,访问该变量名称的时候,会首先找本层作用域是否含有该变量,如果没有就去父层作用域去找,最终找到全局变量为止,如果全局变量也找不到该变量,那么就会报错。
那么如果想在函数fun3外面调用变量a,就要在函数fun3内部再定义一个函数fun4,我们让它返回一下他可以调用的变量a,那么函数fun4的结果就是变量a,那么我们再返回函数fun4,那么我们执行函数fun3,得到的结果就是变量a的值。
简单来讲,就是只要把fun4作为返回值,我们就可以在fun3外部读取它的内部变量了。
四、调用局部变量(使用闭包)要注意什么?
1.闭包会使函数里面的变量被保存在内存中,对于内存的消耗非常大,所以不能滥用闭包,否则网页的性能会降低。
2.不要随便改变父函数内部变量的值。
最后总结一下,闭包就是能够读取其他函数内部变量的函数,能够让我们在父级函数外调用父级函数内的变量,有代码的情况下理解起来其实不难,重要的是在变化莫测的代码中,闭包具体的应用还是需要我们真正的理解它才可以熟练应用。
以上是关于Javascript中的闭包 O__O "…的主要内容,如果未能解决你的问题,请参考以下文章
架构 armv7 的未定义符号:“_OBJC_CLASS_$_Crashlytics”,引用自:AppDelegate.o 中的 objc-class-ref
架构 armv7s 的未定义符号:“_OBJC_CLASS_$_ZXingWidgetController”,引用自:使用 Zxing 的 RootViewController.o 中的 objc-c