[英]Using closures in Javascript
我遇到過這個javascript代碼。
var digit_name = function() {
var names = ['zero', 'one','two'];
return function(n) {
return names[n];
};
}();
alert(digit_name(1));
輸出是一個 。 我知道內部函數被賦給變量digit_name 。 在外部函數的代碼之后在第6行添加括號的需要是什么。 任何人都可以告訴究竟發生了什么?
添加的括號使外部函數執行,如果省略它,它將為您的digit_name
而不是內部函數分配外部函數。
你看到的結尾()
使外部函數立即執行。 因此, digit_name
最終存儲生成的內部函數,而不是指向外部函數的指針。
有關更多信息,請參閱: javascript中自執行函數的用途是什么?
讓我們為這些函數命名,以便更好地了解正在發生的事情:
var digit_name = function outer() {
var names = ['zero', 'one','two'];
return function inner(n) {
return names[n];
};
}();
alert(digit_name(1));
所以,這里有兩個功能: inner
和outer
。 您正在定義一個名為outer
的函數,其目的是創建一個捕獲names
數組的閉包范圍,並定義和返回另一個有權訪問此閉包的函數。 第6行的括號表示調用函數 ,因此賦給digit_names
變量的值不是外部函數,而是內部函數。
var digit_name = function() {...};
=> digit_name
是一個函數
var digit_name = function() {...}();
=> digit_name
是函數返回的對象
var digit_name = function() { // Create outer function
var names = ['zero', 'one','two']; // Define names array, this is done when the outer function is ran
return function(n) { // Return the new inner function, which gets assigned to digit_name
return names[n];
};
}(); // Execute the outer function once, so that the return value (the inner function) gets assigned to digit_name
這里有兩個非常快速的過程。
如果我們寫這個:
function makeDigitReader () { var names; return function (n) { return names[n]; }; }
var myDigitReader = makeDigitReader();
您會正確地猜測myDigitReader將被賦予內部函數。
他們正在做的是跳過一步。 通過添加括號,他們正在做的是在定義它的瞬間觸發函數。
所以你正在發生這種情況:
var myDigitReader = function () {
var names = [...];
return function (n) { return names[n]; };
};
myDigitReader = myDigitReader();
看看發生了什么? 您已將內部函數作為新值返回到以前的外部函數。 因此外部函數不再存在,但內部函數仍然可以訪問names
數組。
您也可以返回對象而不是函數。 並且那些對象屬性/函數也可以訪問最初在函數內部的內容。
通常,您將看到這些立即調用的函數包含在括號中var myClosure = (function() { return {}; }());
。
如果您打算運行一個而不將其返回值賦值,那么您需要將其放在括號中,或者在其前面添加某種操作數,以使編譯器對其進行評估。
!function () { doStuffImmediately(); }(); // does stuff right away
function () { doStuffImmediately(); }(); // ***ERROR*** it's an unnamed function
希望能回答您可能遇到的所有問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.