2014-01-23 181 views
1

我正在閱讀一本很棒的javascript書籍,John Resig和Bear Bibeault的Javascript Ninja的祕密。我到了他們正在展示一種可能的方式來「擴展」Array類的一部分。 (因爲他們沒有真正擴展它)這是從示例代碼:擴展數組和閉包

function MyArray() {} 
MyArray.prototype.length = 0; 

(function() { 
    var methods = ['push', 'pop', 'shift', 'unshift', 'slice', 'splice', 'join']; 
    for (var i = 0; i < methods.length; i++) (function(name) { 
     MyArray.prototype[ name ] = function() { 
      return Array.prototype[ name ].apply(this, arguments); 
     }; 
    })(methods[i]); //<-This one 
})(); 
var mine = new MyArray(); 
mine.push(1, 2, 3); 

我是一個JavaScript專家很遠,有時會發現瓶蓋有問題的,所以我的問題是:什麼是需要內立即功能?如果我這樣寫:

for (var i = 0; i < methods.length; i++) { 
    MyArray.prototype[methods[i]] = function() { 
     return Array.prototype[methods[i]].apply(this, arguments); 
    }; 
}; 

控制檯會記錄:ReferenceError:引用未定義的屬性方法[i]。這是否意味着MyArray.prototype實際上沒有分配方法,直到我調用其中的一些方法?或者這裏有什麼竅門?非常感謝!

回答

1

與循環的問題是i變量是循環的所有迭代被抓獲的同一個,所以最終的效果是,在所有原型方法最終會調用methods[methods.length](因爲i將結束值爲methods.length),這是未定義的!

這就是爲什麼你需要分別捕獲每個i,並在循環內創建閉包是一種方法。

看看控制檯的這jsfiddle看到在行動。

+0

啊,當然,我想我現在看到它。所以這:MyArray.prototype [methods [i]] = function()被正確賦值,所以MyArray.prototype實際上包含了正確的方法。但在我打電話給他們的那一刻,它看着Array.prototype [methods [i]],而且我太大了,它變成了Array.prototype [undefined]。那是對的嗎? – Fygo

+0

是的,就是這樣@Fygo,你懂了! –