• 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]())
    }
    

      注释:参考孔浩

  • 相关阅读:
    Mysql 创建表
    oracle数据库 ORA-01017的解决办法
    用Html创建简历
    Mysql 基本的增删改查
    Linux 基本操作
    几乎百度
    测试第二天
    java map接口,可变参数,Collections集合工具类
    java set接口
    java List接口
  • 原文地址:https://www.cnblogs.com/linfangshuhellowored/p/4349053.html
Copyright © 2020-2023  润新知