zoukankan      html  css  js  c++  java
  • Javascript闭包(Closure)

    1.Javascript特殊的变量作用域。
    变量的作用域无非就是两种:全局变量和局部变量。
    Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。

    function f1() {
        var n = 999;
    }
    alert(n); // error没有变量n

    函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!

    function f2() {
        n = 999;
    }
    f2();
    alert(n); // 999

    2.Javascript语言特有的"链式作用域"结构(chain scope),

    子对象会一级一级地向上寻找所有父对象的变量。
    父对象的所有变量,对子对象都是可见的,反之则不成立。

    3.什么是闭包:
    当内部函数在定义它的作用域的外部被引用时,就创建了该内部函数的闭包

    这个不是闭包

    function f3(x) {
        var temp = 3;
        function bar(y) {
            temp = temp + 1;
            alert(x + y + temp);
        }
        bar(10);
    }
    f3(2) //2+10+4=16; 不管执行多少次,都会alert 16,因为bar能访问foo的参数x,也能访问f3的变量tmp。这个不是闭包

    闭包

    function f4(x) {
        var temp = 3;
        return function (y) {
            temp = temp + 1;
            alert(x + y + temp);
        }
    }
    var bar = f4(2); // bar 现在是一个闭包
    bar(10);//第一次16,第二次17,每次自动加1
    f4(2)(10); //这个每次都是16,因为每次都是一个新的对象,这个对象是不存在的,与上面的区别是上面的已经存在。
    function f5() {
        var n = 999;
        nAdd = function () { n += 1 } //nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量
        function f6() {
            alert(n);
        }
        return f6;
    }
    var result = f5();
    result(); // 999
    nAdd();   
    result(); // 1000
    
    var name = "The Window";
    var object = {
        name: "My Object",
        getNameFunc: function () {
            alert(this.name);  //My Object
            return function () {
                return this.name; //当前的name,没有的话当成全局变量
            };
        }
    };
    alert(object.getNameFunc()()); //The Window
    
    var name = "The Window";
    var object = {
        name: "My Object",
        getNameFunc: function () {
            var that = this;
            return function () {
                return that.name;
            };
        }
    };
    alert(object.getNameFunc()());//My Object

    4.闭包的注意点:

    1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
    2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

  • 相关阅读:
    W3C代码标准规范
    我们为什么要遵循W3C标准规范
    WEB标准:标准定义、好处、名词解释、常用术语、命名习惯、浏览器兼容、代码书写规范
    ThinkPHP框架下,给jq动态添加的标签添加点击事件移除标签
    ThinkPHP框架下,jq实现在div中添加标签并且div的大小会随之变化
    Windows下spark1.6.0本地环境搭建
    Mysql中使用SQL计算两个日期时间差值
    jquery正则表达式验证:手机号码
    jquery正则表达式验证:验证邮箱格式是否正确
    jquery正则表达式验证:整数12位,小数钱12位小数点后2位
  • 原文地址:https://www.cnblogs.com/zhao123/p/6838575.html
Copyright © 2011-2022 走看看