【问题标题】:Extending Array and closures扩展数组和闭包
【发布时间】:2014-01-23 18:05:00
【问题描述】:

我正在阅读 John Resig 和 Bear Bibeault 撰写的一本很棒的 JavaScript 书籍,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: reference to undefined property methods[i]。这是否意味着 MyArray.prototype 实际上没有分配方法,直到我调用它的一些方法?或者这里的诀窍是什么?非常感谢!

【问题讨论】:

    标签: javascript methods closures prototype


    【解决方案1】:

    您的循环的问题是i 变量与循环的所有迭代中捕获的变量相同,因此最终效果是MyArray 中的所有原型方法最终都会调用methods[methods.length] (因为i 最终会得到值methods.length),这是未定义的!

    这就是为什么您需要分别捕获每个i,并且在循环内创建闭包是一种方法。

    查看此jsfiddle 的控制台以了解其实际效果。

    【讨论】:

    • 啊,当然,我想我现在明白了。所以这个: MyArray.prototype[methods[i]] = function() 被正确分配,所以 MyArray.prototype 实际上包含正确的方法。但是在我调用它们的那一刻,它查看 Array.prototype[methods[i]] 并且 i 太大,它变成了 Array.prototype[undefined]。对吗?
    • 是的,就是这样@Fygo,你明白了!
    猜你喜欢
    • 2019-06-16
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    • 2016-08-02
    • 2014-07-27
    • 2023-03-09
    相关资源
    最近更新 更多