• 理解JAVASCRIPT 闭包


    最近去面试了一家企业,结果非常灰心丧气,于是周末给自己定了一个目标

    学好一门,学精通一门。不求多,只求懂。

    最近看到一个概念“闭包”。

    什么是闭包呢?

    简单一点就是:看得到多和看得到少的区别。

    上面这句话是我自己总结的,或许不太准确。

    你能看到的多少这句话该如何理解呢?

    下面随便丢一段代码:

    var name="Peter";
    
    function outer()
    
    {
    
      var name="Tom";
    
      function inner()
    
      {
    
        return this.name;
      }
    
      return inner;  //返回函数inner,作为OUTER的一个返回值
    
    
    
    }
    
    var flag=outer();
    
    alert(flag()); //Peter
    

     大家也许会比较的疑惑,为什么返回的是Peter而不是Tom?

    是不是认为编程的就近原则?

    答案是:你还没有很好的理解闭包。

    下面的一张图可以帮助大家理解一下,定义了一个flag对象,然后公共的函数是inner的父函数outer,

    其实执行的是inner函数,因为outer函数返回对INNER函数的一个引用。

    然后alert就是执行这个函数inner了。

    我们要理解为什么是Peter而不是Tom,还需要了解一下闭包的作用域链。

    那么,什么是作用域链呢?

    看下面的代码;

    function num()
    {
    	var number=0; //结果为4
            //number=0;    //结果为1
        
    	number++;
    }
    var number=4;
    num();
    
    alert(number);
    

      如果运行上述代码,在function内加var 和不加var的区别是很大的。

    这就是文章下面要提到的JAVASCRIPT链式结构;

    如果不声明var,那就表示这是一个全局变量,记住这一点概念很重要。

    而在函数内部加了var以后,试想一下,外面的这个number和里面的number就没有任何的关系了,

    所以最后的结果是4,是全部的number起作用。

    如果没加var关键字,那么number就是属于window下的,默认this指向window(this.number),

    外层的var=4会被自动替换成1.

    如果想alert的值为4,只有一个办法,把

    var number=4;
    num();
    

    的顺序替换一下^_^。

    闭包的特性之一,就是可以在函数外部通过对象调用到函数内部的局部变量。

    就好像是C#中,私有的变量,必须通过getter,setter方法来进行调用一样。

    说白了,闭包,就是和上面说的可以类比。

    再回到上面的问题,为什么name是window的而非function内部的局部变量的呢?

    大家有没有发现 var flag=outer()这句话。

    其实flag对象是指向window的。

    而这个outer函数其实是返回了一个inner的引用。

    所以,inner里的this.name(等同于outer().name)也被变成了一个window对象的引用。

    所以,闭包不仅可以在外面访问函数内部的变量,

    还可以改变内部变量的值,所以这一点大家要注意了,

    非常危险的!慎用闭包。

    比如下面的代码

    name="Peter";
    
    var obj={
    
    name:"yang",
    
    innerFunc:function()
    
      {
    
    return function()
    
    {
    
     return this.name;
    
    }
    
      }
    
    }
    
    alert(obj.innerFunc()()); //Peter
    

    通过外面可以改变里面局部变量的值,让其指向全局变量。

    所以这就相当于形成了一个setter方法。

    大家使用闭包的时候一定要小心啊。

    另外最后再补充一下:

    JAVASCRIPT的链式原理:

    1.内部函数B形式参数,实际参数,函数,内部变量。

    2.内部函数B的原型prototype

    3.外部函数A的形式参数,实际参数,函数,内部变量。

    4.WINDOW对象,活动对象(链式的顶端)

    另外还有一点要注意,就是在闭包的时候,因为外部可以调用到内部函数的变量,并且是Writable的,所以内部

    函数变量是一个“可持久的”,就是可以不受JAVASCRIPT的垃圾回收机制的影响。

    而内部函数的变量根据链式原理对于外部的变量也是可持久的,这就造成了内,外的变量都具有可持久性,

    这就形成了闭包,不过造成了这些变量越积越多,在内存中,从而影响程序的效率。

    这个时候,就要在函数调用结束后删掉一些不必要的变量,否则严重的会造成内存泄漏。

    好了,写完了,话说那个人问我怎么写JQUERY的分页,我没答出来,好好努力吧

    O(∩_∩)O哈哈~

    祝大家周末愉快,我是新手,有写得不合理的地方,请多多指正。




  • 相关阅读:
    C#面向对象--类
    Unity DOTS--面向数据编程前的准备
    C#面向对象--命名空间
    C#面向对象--多态
    C#面向对象--继承
    C#中堆和栈的区别
    sql执行顺序
    cookie session
    栈和队列
    c# 单例模式
  • 原文地址:https://www.cnblogs.com/kmsfan/p/3734043.html
Copyright © 2020-2023  润新知