js 闭包之一

既然说闭包的化,我们就先来说说函数。慢慢的进入进入正题

(1)函数申明 

f1();
function  f1(){
alert("1")
}//结果 1

(2)函数定义

f1();
var f1=function(){
alert(''1")
}//  直接报错了

其实原因是这样的函数申明:会在代码执行之前提前加载到作用域中这样在执行发f1()的时候就可以找到了。但是函数的定义是:先在内存里卖弄创建了一块区域,之后通过一个f1() 指针指向这块区域,开始的时候这块区域是没有名字的.

函数的作用域链

var number="a";
var showNumber=function(){
alert(this.number);
}
function changeNumber(){
var anothernumber="b";
function savenumber(){
var tempnumber=anothernumber;
anothernumber=number;
number=tempnumber
}
savenumber();
}
changeNumber();
showNumber()  //结果是“b”

其实我的理解就是,在进行js 函数调用的时候,会为每一个函数自动的添加一个scope属性通过这个属性来指向一块内存,然后这个内存就会包含这个这个函数的上下文相关的变量,如果这个函数里面又包含了一个新的函数,那么又会自动的分配一块内存,当然这个函数又会自动的继承了他的上级所执行的变量(这个继承可能说的不太对感觉是这个意思?)

函数作用域链:示意图

其实可以这么理解哈。我们在带调用changnumber()的时候首先changenumber()这个函数的作用域链包括自己的(anothernumber 这个变量,然后就是savenumber()。最后就是上文的作用域,也就是number()和shownumber()这个全局的。这个时候savenumber 也会被执行那么他就会去继承他的上一级的作用域,和上上级的作用域,)那么这个时候savenumer去改变number 的值,这个时候number 的值就是b,最后当我们调用shownumber()的时候自然出现的值就是结果“b”了。

我看一个例子看看闭包产生的原因:

function  compareObjectFunction(prop){
//匿名函数
return function(obj1>obj2{
if(obj1[prop]>obj2[prop])   return 1;
else if(obj1[prop<obj2[prop]])   return -1;
else return 0;
})
}
var o1={name:"Leon",age:23};
var o2={name:"Ade",age:28};
/*
在中这个时候变量并没有被释放,于是这个时候作用域就变大了
*/
var compare=compareObjectFunction("age");
var rel=compare(o1,o2);
alert(rel1)

我们看看他的作用域链

 于是我们来解释一下到底是如何实现的。首先我们执行compareobjectfunction()的时候会产什么如下的作用域链Global和compareobject()这个。当compareobjecfunction执行完过后我们就会释放相应的作用域但是这个时候com这个匿名函数指向了相同的作用域,Global和compareobject()这个时候并不会发生释放这个作用域的动作,于是compar、这个就获取到相应的参数了。于是乎作用域就发生了扩大。这个就是闭包产生的原理。其实我的理解就是里面的函数调用了外部函数的变量(或者说扩大了函数的访问变量的范围)

下面我们再来看一个例子:

function fn1(){
var fns=new Array();
for(var i=0;i<10;i++){
fns[i]=function(){
return 1;
}
}
return fns;
}
var fs=fn1();
for(var i=0;i<fs.length;i++)
{
alert(fs[i]())
}

  注释:参考孔浩

原文地址:https://www.cnblogs.com/linfangshuhellowored/p/4349053.html