2016-11-01 61 views
1

在下面的例子中,關於倒閉,我看到:IIFE而沒有圍繞函數語句括號

function addButtons(numButtons) { 
    for (var i = 0; i < numButtons; i++) { 
    var button = document.createElement('input'); 
    button.type = 'button'; 
    button.value = 'Button ' + (i + 1); 
    button.onclick = function(buttonIndex) { 
     return function() { 
     alert('Button ' + (buttonIndex + 1) + ' clicked'); 
     }; 
    }(i); 
    document.body.appendChild(button); 
    document.body.appendChild(document.createElement('br')); 
    } 
} 

window.onload = function() { addButtons(5); }; 

爲什麼沒有定義onclick方法如下?:

button.onclick = (function(buttonIndex) { 
    return function() { 
    alert('Button ' + (buttonIndex + 1) + ' clicked'); 
    }; 
})(i); 

隱而不宣IIFE需要以下語法:(function statement)(arguments)

+0

這裏已經回答:http://stackoverflow.com/questions/31910216 /爲什麼是括號 - 要求在javascript-iife – Saravana

+1

*「IFFE不需要以下語法:(函數語句)(參數)?」*不,立即調用函數本身不需要parens包裝功能。 *所需要的是確保函數被解釋爲函數表達式而不是聲明。因爲函數處於賦值的值的位置,所以它已經被解釋爲一個表達式,所以不需要parens。技術上來說,parens本身並不是必需的;任何接收函數作爲表達式的運算符都應該工作。 –

+0

如果你正在尋找替代品,你可以考慮'.bind' – Rajesh

回答

0

原代碼的工作,因爲IIFE出現在一個賦值,因此不存在歧義,即轉讓的右邊是確實的表達式。

沒有賦值,解析器會誤解它是一個函數聲明,因此會拋出語法錯誤,表明聲明的函數缺少名稱。在這種情況下,括號是使其成爲IIFE所必需的。

但是通常的做法是始終包括IIFE的括號,即使在轉讓中使用時也是如此。

在你手邊的具體情況,您也可以將點擊處理程序使用bind,它返回它需要的功能:

button.onclick = function(buttonIndex) { 
    alert('Button ' + (buttonIndex + 1) + ' clicked'); 
}.bind(null, i); 
0

您可以使用元素的數據集。例如:

function addButtons(numButtons) { 
    for (var i = 0; i < numButtons; i++) { 
    var button = document.createElement('input'); 
    button.type = 'button'; 
    button.value = 'Button ' + (i + 1); 
    button.dataset.buttonIndex = i + 1; 
    button.onclick = function() { 
     alert('Button ' + this.dataset.buttonIndex + ' clicked'); 
    }; 
    document.body.appendChild(button); 
    document.body.appendChild(document.createElement('br')); 
    } 
} 

window.onload = function() { addButtons(5); };