談論javascript閉包
阿新 • • 發佈:2018-02-24
影響 內存占用 被調用 指定 很多 引用 閉包 post gpo )的聲明的變量。
是執行
閉包看似很簡單,其實牽扯了很多東西,例如:上下文作用域、內存占用、局部以及全局變量等
function init() { var name = "Mozilla"; // name 是一個被 init 創建的局部變量 function displayName() { // displayName() 是內部函數,一個閉包 alert(name); // 使用了父函數中聲明的變量 } displayName(); } init();
init是外部函數,name是外部變量。
displayName屬於內部函數調用時使用的是父函數(init()
嵌套的函數可以訪問在其外部聲明的變量,簡而言之就是內部函數可以訪問外部函數。
下面的例子也解釋了作用域對變量的影響,請看如下:
function init() { var name = "Mozilla"; // name 是一個被 init 創建的局部變量 function displayName() { // displayName() 是內部函數,一個閉包 var name = "6666"; alert(name); // 使用了父函數中聲明的變量 } displayName(); } init();
上下文作用域,同名變量局部作用域最大。
function makeFunc() { var name = "Mozilla"; function displayName() { alert(name); } return displayName; } var myFunc = makeFunc(); myFunc();
JavaScript中的函數會形成閉包。 閉包是由函數以及創建該函數的詞法環境組合而成。這個環境包含了這個閉包創建時所能訪問的所有局部變量。在我們的例子中,
myFunc
makeFunc
時創建的 displayName
函數實例的引用,而 displayName
實例仍可訪問其詞法作用域中的變量,即可以訪問到 name
。
由此,當 myFunc
被調用時,name
仍可被訪問,其值 Mozilla
就被傳遞到alert
中。
function makeAdder(x) { return function(y) { console.log(‘:‘ + x); return x + y; }; } var add5 = makeAdder(5); var add10 = makeAdder(10); console.log(add5(2)); // 7 console.log(add10(2)); // 12
在這個示例中,我們定義了 makeAdder(x)
函數,他接受一個參數 x
,並返回一個新的函數。返回的函數接受一個參數 y
,並返回x+y
的值。
從本質上講,makeAdder
是一個函數工廠 — 他創建了將指定的值和它的參數相加求和的函數。在上面的示例中,我們使用函數工廠創建了兩個新函數 — 一個將其參數和 5 求和,另一個和 10 求和。
add5
和 add10
都是閉包。它們共享相同的函數定義,但是保存了不同的詞法環境。在 add5
的環境中,x
為 5。而在 add10
中,x
則為 10。
未完待續。。。
談論javascript閉包