Js函数深入理解-作用域链与闭包

来源:互联网 发布:mac怎么看西瓜影音 编辑:程序博客网 时间:2024/04/28 20:38

Js函数深入理解-作用域链与闭包


作用域链:
var x = 1;
function a(){
var y = 2;
function b(){
var z = 3;
console.log(x+'/'+y+'/'+z);
}
b();
console.log(x+'/'+y);
console.log(x+'/'+y+'/'+z);
}
a();

打印的结果是:



b函数可以访问x,y,z
a函数可以访问x,y,但不能访问z


简单的可以这么理解:
在创建完函数a时就生成两个全局变量对象x和a(),并且存储于内部的Scope属性中,当运行a()会产生y与b()这个两个变量对象,同时复制Scope中的全局变量对象,此时a()里面就会有x、a()、y、b()这四个变量对象,而z是不存在的。当运行b()时会产生z这个变量对象,同时复制之前产生的变量对象,此时b()里面会有 x、a()、y、b()、z五个变量对象


闭包:
指有权访问另一个函数作用域中的变量的函数

function a(){
var y = 2;
return (function(){ //这个就是闭包
var z = 3;
return z;
})()
}
console.log(a())


有些人就会说,为什么不直接返回z,这么麻烦。js既然有闭包,自然有它存在的价值
如看下面的一个例子,把x=100累加
使用全局变量
var y = 100;
function a(){
y = y+1;
return y;
}
console.log(a()) //101
console.log(a()) //102
console.log(a()) //103


如果是项目很大的话,使用全局变量可能会带来灾难性的后果,因为全局变量在哪里都可以被修改,所以如果大量的使用全局变量可能造成命名的冲突,值被修改等问题。


所以这里的闭包就派上用场了
function a(){
var y = 100;
return function(){ //这个就是闭包
y = y+1;
return y;
}
}


var b = a(); //返回闭包函数
console.log(b())//101
console.log(b()) //102
console.log(b())//103


这里有些人可能会有这样的疑问,函数被被执行完了,里面的变量不应该被销毁吗
function a(){
var y = 100;
return y = y+1;
}
console.log(a())   //101每执行完一次,y并不会存储到内存中
console.log(a())   //101
console.log(a())   //101

而闭包的一个作用就是把y存储到内存中,就算函数被运行完也不会被销毁。所以这里就引发了如果滥用闭包的话可能会占用很多的内存,导致效率低下。因此很多时候用完闭包后要及时把它从内存中释放。只需在上述代码
console.log(b())后加一句   b = null; 即可


下面再看一个例子:
function a(){
var y = 100;
return function(){ //这个就是闭包
y = y+1;
return y;
}
}


var b = a(); 
a = null;
console.log(b())
console.log(b())
还能执行吗?
答案是可以的。
var b = a(); 这里的b就是那个返回函数(闭包),当a被运行时会产生一个变量对象 y存储在内存中,一般情况下a被销毁了,那么它的变量对象也会被销毁,但是这里却不会,因为闭包的存在,闭包用到这个变量对象
0 0
原创粉丝点击