假設我們有一個簡單的對象列表:在這裏創建閉包有什麼選擇?
var things = [
{ id: 1, name: 'one' },
{ id: 2, name: 'two' },
{ id: 3, name: 'three' }
];
而我們需要通過這些對象進行迭代並註冊爲後來的一些事件參數。天真的方法分享所有的回調之間對最後項目各大火相同的對象引用,所以:
for (var i = 0; i < things.length; i++) {
var o = things[i];
setTimeout(function() { doSomethingWith(o); }, i * 1000);
}
一個典型的解決方案是創建一個封閉,限制了我們的對象引用的範圍:
for (var i = 0; i < things.length; i++) {
(function() {
var o = things[i];
setTimeout(function() { doSomethingWith(o); }, i * 1000);
})();
}
如果我們不針對IE < 9,我們可以依靠.forEach()
:
things.forEach(function(o, i) {
var o = things[i];
setTimeout(function() { doSomethingWith(o); }, i * 1000);
});
但是,無論如何,我們最終在傳遞一個匿名函數forEach()
時創建了一種閉包。
有沒有一種方法可以在沒有閉包或函數引用的情況下完成此操作?
潛在的問題有三個方面:
- 同樣重要的是:傳入
setTimeout()
(或任何可能)讓你(我)覺得就像你正在創建的函數引用封閉。所以,我傾向於忘記外部封閉。 - 更重要的是:附加函數/閉包聲明鼓勵「箭頭代碼」。對於複雜的操作,複雜操作的代碼可讀性會隨着代碼遷移到屏幕上而迅速惡化......除非應用程序或組織風格指南指定關閉的換行符+縮進,否則這可能在IE> 9中由
.forEach()
解決。 - 大多數重要的是:我很確定有一個簡單的方法來處理這個問題。我覺得現在無法想象它是愚蠢的。
也許更好的方法來問這是:在我們開始強制創建關閉之前,我們都做了什麼惡魔?
*我們使用全局狀態* ...我認爲這就是我正在尋找的。我無法圍繞我們*用來做什麼來管理這種類型的東西,爲什麼我停下來了。但是,我很確定就是這樣。我們擰了很多全球性的東西。 – svidgen 2015-02-24 19:20:08