javascript 中的闭包
要搞清楚闭包,首先要知道javascript中的作用域.
什么是作用域,你可以简单的理解成当前上下文环境.
javascript 中的作用域有2种
属于全局作用域.
属于局部作用域
全局作用域:
比如我们在浏览器端编写的 javascript 代码,
var name=‘test’;
我们直接定义了一个变量name ,那么这个变量当前作用域就是全局,对于浏览器端全局就是window
更确切的说,name 是window 对象的一个属性.
console.log(window.name); //test console.log(name); //test console.log(this.name); //test
上面三种输出方法,结果都是一样的,因为当前作用域就是window对象,this指向当前作用域.
局部作用域:
此类作用域是针对javascript中函数的作用域.
是指在函数内部定义的变量,如下:
function test(){ var name=‘yijiebuyi’; alert(this.name); }
上面 name 是一个局部变量,定义在函数内部,所以它的作用域就是此函数内部可以访问.
alert(this.name); this 指向当前作用域,因为在函数内部,所以指函数作用域.
如果函数外部 alert(name); 将会报错,返回 undefined
但是 函数内部可以访问函数外部作用域,如下:
var name=‘test’; function test(){ alert(name); //test }
上面的代码没有问题,函数内部作用域可以访问全局作用域,(或者简单理解成 函数内部作用于可以访问它父级作用域)
既然函数可以访问父作用域变量,而且函数是一等公民,可以当做参数,返回值等.
那么问题来了:
function test(){ var name=‘yijiebuyi’; return function(){ console.log(name); } }
var rtn=test(); rtn(); //yijiebuyi
我们上面运行 rtn() ,得到 yijiebuyi,说明了2个问题:
1.函数确实是头等公民,可以当参数,可以当返回值.
2.函数可以访问它的父作用域,因为成功输出了 yijiebuyi
我们再换一个思路:
如果我不返回这个匿名函数,但是我想得到 test 函数中的 name 属性值,怎么办?
好像不行,办不到,只能返回一个函数来获取 test 函数内部变量了,其实这个过程就是 一个典型的闭包!
我们在返回匿名函数的时候并没有返回 var name=‘yijiebuyi’ 但是运行 rtn 函数却得到了 name 属性值.
所以:
闭包的作用就是:把函数内部私有变量暴露出来. (暴露作用域)
闭包如何实现:函数里面返回一个函数.
这个返回函数自动带上了父函数所在的作用域,所以可以访问其内部变量,
也正是因为闭包的存在,导致父函数执行完成后并没有被垃圾回收,它的作用域内的变量都将保存在内存中供闭包使用.