zoukankan      html  css  js  c++  java
  • 我认知的javascript之作用域和闭包

      说到javascript,就不得不说javascript的作用域和闭包;当然,还是那句老话,javascript在网上都说得很透彻了,我也就不过多的强调了;

    作用域:javascript并没有像其他的后台语言那样有块级作用域(es6推出了一些新的语法与特性,在这儿就不多说了,有兴趣的可以点这里),那么js的作用域有哪些呢?

         1.全局作用域:全局作用域一般称之为window,无论什么地方(function),都能调用到window作用域上的东西;

         2.局部作用于(function):前面说过,javascript在es6之前不存在块级(两个大括号之间)作作用域,那么,这儿说的局部作用于就是function内的作用域,也就是说,两个同级的function不能调用到对方内部定义的变量。 

      再说作用域之前,看下面一个例子(也算是作用域):

    window.socpe= "window";//作用域A
    (function(){//作用域B
        var socpe = "function";
        function Socpe(){//作用域C
            var socpe = "Socpe";
            console.log(socpe);//socpe = "Socpe";
        }
        Socpe();
        console.log(socpe);//socpe = "function";
        console.log(window.socpe);//socpe = "window";
    })()
    var socpe = "custom";
    console.log(socpe);//socpe = "custom";
    console.log(window.socpe);//socpe = "custom";

      在上面的例子中可以看到,javascript在查找变量的时候,是返回找到的第一个,通过var可以重复定义(涉及到js的编译,后面说明),同级作用域下重复定义会导致重新赋值,子级作用域重新定义会在当前作用域覆盖并且不影响父级作用域;当然,这儿这是提醒大家有这么回事,但不建议大家这么操作;

      特殊的东西说了,现在来说比较正常的:

    window.socpe= "window";//作用域A
    (function(){//作用域B
        socpe = "function";
        function Socpe(){//作用域C
            socpe = "socpe";
            console.log(socpe);//socpe = "socpe";        
        }
        Socpe();
        console.log(socpe);//socpe = "socpe";
        console.log(window.socpe);//socpe = "socpe";
    })()
    console.log(socpe);//socpe = "socpe";

      上面这个例子,就可以明显的看到,子级可以调用并改变父级作用域的变量;

    闭包:闭包,在javascript中,非常的重要,了解了闭包,才能规避一些不必要的错误,写出更优雅的代码;在说闭包之前,先说说javascript的回收机制:在javascript也的垃圾回收是自动完成的,简单点就是:会找出不再使用的变量,然后释放掉其占用的内存,但是这个过程不是时时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。

    var ClosureTest =(function(){
        var a = 0;    
         return function(){
             console.log(++a);         
         };
    })()
    ClosureTest();//1
    ClosureTest();//2
    ClosureTest();//3

      上面的例子,就是一个典型的闭包。下面我就来说一下不理解闭包而产生的错误结果:

    var myArry = [],
        i = 0,
        j = 0;
    for(i = 0; i < 9; i++) {
        myArry[i] = function() {
            console.log(i);
        };
    }
    for(j = 0; j < 9; j++) {
        myArry[j](); // 9
    }
    myArry = [];
    for(i = 0; i < 9; i++) {
        myArry[i] = (function(a) {
            return function() {
                console.log(a)
            };
        })(i);
    }
    for(j = 0; j < 9; j++) {
        myArry[j](); // 1 - 9
    }

      上面的代码中,第一个循环看着的对的,也没有什么毛病,但是结果却并不是我们想要的;而第二个i循环,就用闭包知识,多余的我也就不多说了,可以考虑思考一下为什么第二个i循环就能得到我们想要的正确结果呢!

      好了,闭包和作用域就说到这儿,由于水平有限,多多包涵,欢迎指出不正确的地方!

  • 相关阅读:
    HDU
    HDU
    CodeForces
    HDU——2955 Robberies (0-1背包)
    南京区域赛之后
    算法作业三-哈夫曼编码
    HDU
    POJ 1220 NUMBER BASE CONVERSION(进制转换,大数)
    HDU 1535 Invitation Cards(最短路)
    HDU 3572 Task Schedule(网络流+当前弧优化)
  • 原文地址:https://www.cnblogs.com/xiaoxiaoqiye/p/6985188.html
Copyright © 2011-2022 走看看