闭包 : 闭包就是一个函数引用另外一个函数的变量,因为变量被引用着所以不会被回收,因此可以用来封装一个私有变量。
当内部函数在定义它的作用域的数据外部被引用时,就创建了该内部函数的闭包,如果内部函数引用了位于外部函数的变量,当外部函数调用完毕后,这些变量在内存不会被释放,因为闭包需要它们
变量的作用域 : 作用域就两种,全局作用域和局部作用域
var n=999; function f1(){ alert(n); } f1(); // 999 function f2(){ var m=999; } alert(m); // error function f3(){ i=999; // 函数内部声明变量的时候,一定要使用 var 声明变量,如果不用 var,此时改变量就变成全局变量 } f3(); alert(i); // 999
从外部读取局部变量 : 正常情况下是办不到的,但可以在函数的内部再定义一个函数,这样内部函数就可以访问外部函数的变量。另外,外部函数无法访问内部函数变量,这就是 JavaScript 语言特有的 "链式作用域" 结构
function f1() { var n = 999; function f2() { alert(n); } return f2; } var result = f1(); result(); // 999
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中
function f1() { var n = 999; nAdd = function(){ // nAdd 是全局变量 n += 1; } function f2() { alert(n); } return f2; } var result = f1(); result(); // 999 nAdd(); result(); // 1000
1> 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除
2> 闭包会在父函数外部,改变父函数内部变量的值。所以,如果把父函数当作对象 (object) 使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值
var name = "The Window"; var object = { name : "My Object", getNameFunc : function() { return function() { return this.name; }; }, getNameFunc2 : function() { return () => this.name; }, getNameFunc3 : function() { this_ = this; return function() { return this_.name; }; } }; alert(object.getNameFunc()()); // The Window,this 指向调用的对象,此处执行的时全局 this alert(object.getNameFunc2()()); // My Object,使用箭头函数相当于 getNameFunc3 的写法 alert(object.getNameFunc3()()); // My Object
function outerFun() { var a =0; alert(a); } var a = 4; outerFun(); // 0 alert(a); // 4
function outerFun() { a = 0; // 没有 var,此时 a 是作用于全局变量,将修改全局变量的 a alert(a); } var a=4; // 全局变量 a outerFun(); // 0 alert(a); // 0
function createFunctions() { var result = new Array(); for (var i=0; i < 10; i++) { result[i] = function() { return i; }; } return result; } var funcs = createFunctions(); for (var i=0; i < funcs.length; i++) { // 打印出 10 个 10,在 js 中使用 () 才会执行函数 console.log(funcs[i]()); }
以上是详解JavaScript之闭包的详细内容。更多信息请关注PHP中文网其他相关文章!