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),性能

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

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

这个不是闭包code

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.闭包的注意点:blog

1)因为闭包会使得函数中的变量都被保存在内存中,内存消耗很大,因此不能滥用闭包,不然会形成网页的性能问题,在IE中可能致使内存泄露。解决方法是,在退出函数以前,将不使用的局部变量所有删除。
2)闭包会在父函数外部,改变父函数内部变量的值。因此,若是你把父函数看成对象(object)使用,把闭包看成它的公用方法(Public Method),把内部变量看成它的私有属性(private value),这时必定要当心,不要随便改变父函数内部变量的值。ip

相关文章
相关标签/搜索