閉包 : 閉包就是一個函數引用另一個函數的變量,因為變數被引用所以不會被回收,因此可以用來封裝一個私有變數。
當內部函數在定義它的作用域的資料外部被引用時,就創建了該內部函數的閉包,如果內部函數引用了位於外部函數的變量,當外部函數調用完畢後,這些變數在記憶體不會被釋放,因為閉包需要它們
變數的作用域: 作用域就兩種,全域作用域和局部作用域
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中文網其他相關文章!