javascript - 替换 'New' 的规则

标签 javascript prototype

在他的“Good Parts”中,Crockford 建议永远不要使用“new”。要遵循该规则,您将如何重构以下代码?

function Range(from, to) { 
    this.from = from; 
    this.to = to; 
} 

Range.prototype = { 
    includes: function(x) {
        return this.from <= x && x <= this.to;
    }, 

    foreach: function(f) { 
        for(var x = Math.ceil(this.from); x <= this.to; x++) f(x);
    },

    toString: function() { 
        return "(" + this.from + "..." + this.to + ")"; 
    } 
};

// Here are example uses of a range object 
var r = new Range(1,3); // Create a range object 
r.includes(2); // => true: 2 is in the range 
r.foreach(console.log); // Prints 1 2 3

我发现了他的 additional advice ,但不清楚如何在这种情况下应用它(大概很常见)。他会建议创建一个包含巨大对象字面量的工厂函数吗?如果是,那不是效率低下吗? ISTM 这样的工厂函数在每次调用时都会创建重复的函数。换句话说,没有一个原型(prototype)持有共享的自定义方法。

他的建议中似乎有些东西没有说,我希望有人能澄清一下。

最佳答案

在这里,我将展示如何在不使用 new

的情况下实现这一目标
Range = function(from, to) {

    function includes(x) {
        return this.from <= x && x <= this.to;
    }

    function foreach(f) {
        for (var x = Math.ceil(this.from); x <= this.to; x++) f(x);
    }

    function toString(){
        return "(" + this.from + "..." + this.to + ")";
    }

    return {
        from: from,
        to: to,
        includes: includes,
        foreach:  foreach,
        toString: toString
    };
};

var r = Range(1, 3);
console.log(r.includes(2)); // => true: 2 is in the range
r.foreach(console.log); // Prints 1 2 3

这只是一个例子,但我会遵循@nnnnnn 所说的 - “只在适当的时候使用它。就我而言,你问题中的代码完全可以很好地使用 new 并且不需要重构。”

编辑:

下面给出的代码将避免创建重复的函数实例

Range = function(from, to) {
    return {
        from: from,
        to: to,
        includes: Range.includes,
        foreach:  Range.foreach,
        toString: Range.toString
    };
};

Range.includes = function(x) {
    return this.from <= x && x <= this.to;
}

Range.foreach = function (f) {
    for (var x = Math.ceil(this.from); x <= this.to; x++) f(x);
}

Range.toString = function() {
    return "(" + this.from + "..." + this.to + ")";
}

关于javascript - 替换 'New' 的规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9561343/

相关文章:

javascript - 将原型(prototype)添加到现有对象

jquery - this.toPlatedString 不是函数原型(prototype)

javascript - 为什么Object.prototype的__proto__是另一个Object.prototype?

javascript - 在对象构造函数中,如何附加具有自定义键值的属性?

javascript - Bootstrap Datepicker - 使用多日期设置开始日期

javascript - 如何防止用户在 Jquery Mobile 中点击浏览器后退按钮时离开页面?

javascript - jqplot、highcharts、flot如何从轴刻度处捕获点击事件

javascript - 如何在 JavaScript 中处理嵌套的 XML 结构?

javascript - 对 "Object.__proto__ === Function.prototype"返回 "true"感到困惑

javascript - 如果元素包含该名称,则使用 'for' 循环从元素中删除类名称,否则什么也不做