JS:閉包
阿新 • • 發佈:2019-05-10
也會 () 因此 cti ref return style not 導致
一、變量的作用域
要理解js的閉包,首先要了解js的變量作用域;
(1)js的變量有兩種:全局變量,局部變量;
js的局部變量只會在函數內部通過var聲明產生,不是通過var聲明的變量也會被當成局部變量
var a = ‘a‘; function myFunc() { var b = ‘b‘; c = ‘c‘; } myFunc(); console.log(a); // output: a console.log(c); // output: c console.log(b); // output: Uncaught ReferenceError: b is not defined
上面結果:a, c都能在全局訪問,都是全局變量, b不能再全局訪問,所以是局部變量。c雖然定義在內部,但是由於沒有通過var時聲明,所以是全局變量。
(2)變量的作用域
看下面的例子:
var a = ‘a‘; function myFunc() { var b = ‘b‘; console.log(‘inner func:‘, a); // a console.log(‘inner func:‘, b); // b } myFunc(); console.log(a); // output: a console.log(b); //output: Uncaught ReferenceError: b is not defined
從上面的例子可以看出,函數內部可以讀取函數外部的變量,而函數外部不可以讀取函數內部的變量。
二、閉包
某些情況下,需要在函數外部訪問函數內部的變量,正常情況是辦不到的。但是我們可以想個辦法:在函數內部再定義一個函數,然後再把該函數作為返回值返回,我們就可以實現在函數的外部,讀取函數內部的變量了。而作為返回值的這個函數就是閉包。
function f1() { var n = 999; function f2() { console.log(f2就是閉包,可以讓外部訪問內部函數的變量n。 有些人會有疑問,在f1中直接返回n不也可以讓外部訪問內部函數的變量了嗎?就像下面這樣:++n) } return f2; }
function f1() { var n = 999; return ++n; } var result1 = f1(); // 1000 var result2 = f1(); // 1000上面雖然能訪問變量,但是n在函數執行完之後就被銷毀了,沒有被保存下來。但是用下面的這個方法,雖然外部函數在執行完之後被銷毀了, 但是n就被保存下來了:
function f1() { var n = 999; function f2() { return ++n; } return f2; } var result = f1(); result(); // 1000 result(); // 1001 result(); // 1002
因此閉包有兩個用處:(1)可以使函數外部讀取函數內部的變量; (2)讓函數內部的變量始終保存在內存中。
因為閉包會使函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存泄露。解決放法是:在退出之前, 將不使用的局部變量全部刪除;
JS:閉包