您的位置:首页 > Web前端 > JavaScript

JavaScript面向对象学习笔记——闭包

2017-04-11 14:26 441 查看

作用域

JavaScript不存在大括号级的作用域,但是有函数作用域,在函数内定义的变量在函数外是不可见的,但是该变量在某个代码块中定义(比如if或者for语句中),它在代码块外是可见的。

var a = 1;function f(){var b = 1;return a;}


这里变量a是属于全局域的,变量b的作用域就在函数f()内了,所以在f()内a和b都是可见的,在f()外a是可见的,b是不可见的。

如果在函数f()中定义了另一个函数n(),那么在n()中可以访问的变量既可以来自它自身的作用域,也可以来自其父级的作用域,这就形成了一条作用域链,该链的长度取决于实际的需要。

var a = 1;
function f(){
var b = 1;
function n(){
var c =3;
}
}


词法作用域

JavaScript中每个函数都有一个自己的词法作用域,每个函数在被定义时而不是执行时都会创建一个属于自己的环境即作用域;

function f1(){var a = 1;f2();}
function f2(){return a;}
f1();




在函数f1()中调用了函数f2(),由于局部变量a也在f1()中,但是f2()是不可以访问a的,因为当f2()被定义时不是被执行时,变量a是不可见的。和f1()一样,它那时候只能访问自身作用域和全局作用域中的内容,也就是说,这里的f1()、f2()之间不存在共享的词法作用域。尽管当函数被定义时它会记录自身所在环境和相关的作用域链,但是这并不意味着函数也会对其作用域中的每个变量进行记录,正好相反,可以在函数中对变量执行添加、移除和更新,函数只会看到该变量的最终状态。另外,即使f2()还没有被定义,也可以在f1()的定义中包含对f2()的调用,因为对f1()而言,其所知的作用域的任何东西都是可用的。

利用闭包突破作用域链

首先是全局作用域,可以看作是包含一切的宇宙



其中可以包含各种变量比如a和函数比如f



每个函数也都有一块属于自己的私有空间,用于存储一些别的变量和函数,所以:



假如在图中的a点,那么就是位于全局空间中,如果是在b点,就是子啊函数F的空间里,在这里既可以访问全局空间也可以访问F空间,如果是在c点,那就是位于函数N中,在这里可以访问的空间包括全局空间、F空间和N空间。其中,a和b之间是不联通的,因为b在F外是不可见的,但是,b和c是可以连通的,或者说N和b可以连通,当把N的空间扩展到F外,并止步于全局空间以内时,就产生闭包。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息