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 属性值.


所以:

闭包的作用就是:把函数内部私有变量暴露出来. (暴露作用域)

闭包如何实现:函数里面返回一个函数.


这个返回函数自动带上了父函数所在的作用域,所以可以访问其内部变量,

也正是因为闭包的存在,导致父函数执行完成后并没有被垃圾回收,它的作用域内的变量都将保存在内存中供闭包使用.



回到顶部