一、闭包的作用
JavaScript中闭包是一个很难理解的概念,也是衡量JavaScript功力的重要标准。JavaScript语法中的独特特性也通过闭包淋漓尽致的体现了出来。
在学习闭包的过程中,很多同学最大的困惑其实并不是语法本身,而是看着闭包的语法不知道它是干什么用的。难道闭包仅仅是一项供奉在象牙塔中供学术研究者膜拜的高冷课题吗?
其实并不是这样,闭包的本质是将一个函数中某些变量的作用域延伸到函数外部的技术。所有需要突破作用域链,在函数外部访问函数内部变量值的场合都可以使用闭包。具体的例子我们看过语法后再讲述。
二、作用域链
1.作用域
在JavaScript中,变量也可以分为全局变量和局部变量。
①全局变量
直接在script标签内声明的变量就是全局变量
var global = “Hello I am Global”; console.log(“global=”+global); |
执行结果:global=Hello I am Global |
②局部变量
在函数中声明的变量是局部变量
function myMethod() { var localVariable = “Hello I am Local”; console.log(“localVariable=”+localVariable); } myMethod(); |
执行结果:localVariable=Hello I am Local |
但是在函数中声明变量时如果没有指定var关键字那么也是全局变量
function mySpecialMethod() { specialVariable = “Hello I am Specail”; } mySpecialMethod(); console.log(“specialVariable=”+specialVariable); |
执行结果:specialVariable=Hello I am Specail |
③变量可见性
函数中可以使用全局变量,但函数外不能使用局部变量。
var global = “Hello I am Global”; console.log(“global=”+global); function accessGlobal() { console.log(“access global in function=”+global); } accessGlobal(); |
执行结果: global=Hello I am Global access global in function=Hello I am Global |
function myMethod() { var localVariable = “Hello I am Local”; console.log(“localVariable=”+localVariable); } myMethod(); console.log(“access localVariable in global=”+localVariable); |
执行结果: localVariable=Hello I am Local Uncaught ReferenceError: localVariable is not defined |
2.作用域链
作为一门奇葩语言,JavaScript允许在函数内部再声明函数。以下为了称呼方便,我们把包含函数声明的函数称为父函数,把在函数内声明的函数称为子函数。子函数中当然可以再继续声明孙子辈的函数,并且“子子孙孙无穷匮也”。
//父函数 function father() { //子函数 function son() { //… function grandSon() { //… } } } |
从作用域的角度来说,子函数可以访问父函数中声明的变量以及祖先函数中的变量,但父函数不可以访问子函数中声明的变量,这就是作用域链。