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