2014-01-23 137 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,你懂了! –