2

所以假设我想在 JS 中创建一个简单的 Price 类。它基本上是一个数字,所以我想我会从一个数字继承。这是一些代码:

Number.prototype.toMoney = function (precision, decimals, thousands) {
    // Formats number...
}

function Price(val) {
    Number.call(val); // Based on MozillaDN
}

Price.sufix = ' EUR'; // To print with every Price

// Price.prototype = Number.prototype;
Price.prototype = new Number(); // any difference?

Price.prototype.toString = function() {
    return this.toMoney() + Price.sufix; // Of course it does not work.
}

var price = new Price(100.50);
alert(price.toString()); // Gives: undefined EUR
alert(price); // This fail. I thought it should work as it works with Numbers.

我可能做错了什么,但我不知道是什么。

4

3 回答 3

2

当我在寻找几乎相同问题的答案时,我找到了这个页面。由于这有助于我得出最终结论,因此我很乐意与您分享。确实可以从 Number 继承自己的对象。

function Price(val) {
    Number.call(this, val);
}

这是您通常调用父对象的构造函数的方式,但在这种情况下它不起作用,因为构造函数返回val自身。当您尝试阅读时val,会收到“Number.prototype.valueOf is not generic”错误。

alert(price.toString()); // Gives: undefined EUR
alert(price); // This fail. I thought it should work as it works with Numbers.
alert(price.valueOf()); // This fails too! ()

相反,您应该在 Price 类中创建一个名为val.

function Price(val) {
    this.val = val;
}

Price.sufix = ' EUR'; // To print with every Price

// Price.prototype = Number.prototype;
Price.prototype = new Number(); // any difference?

在 JavaScript 中有一种方法可以做一个继承对象,Object.create()方法。而且因为构造函数对象现在指向父构造函数,...

Price.prototype = Object.create(Number.prototype);
Price.prototype.constructor = Price;

最后,您可以覆盖valueOf()读取值的方法:

Price.prototype.valueOf = function(){
    return this.val;
    }

var price = new Price(100.50);
alert(price); //should work now

但是,有一个副作用:如果您需要 Number 对象中的方法,则必须像这样调用它们:

alert(price.valueOf().toFixed(2));
于 2015-03-24T23:25:42.267 回答
0

我认为您在这一行中有一个错字:

Price.prototype - new Number(); // any difference?

您正在分配一个新 Number 作为 Price 的原型,因此您需要使用 = 符号而不是减号。

它应该是:

Price.prototype = new Number(); // any difference?

说了这么多,还是不行。我不明白您为什么要尝试从 Number 继承。

这有效:

function Price(val) {
    this.val = val;                
}
Price.suffix = ' EUR'; // To print with every Price

Price.prototype = {
    toString: function() {
        return this.toMoney() + Price.suffix;
    },
    toMoney: function(precision, decimals, thousands){
        //fancy code here to format the number
        return "formatted number " + this.val;
    }
};

var price = new Price(100.50);
alert(price.toString()); // returns: formatted number 100.50 EUR
alert(price); 
于 2012-06-09T14:07:27.530 回答
0

你的构造函数没有按照你的想法做:

function Price(val) {
    Number.call(val); // Based on MozillaDN
}

当作为构造函数调用时,上面将返回一个普通对象(函数的this对象),而不是Number.call(val)原始值 +0 返回的值,无论val. 所以即使你试图返回它,构造函数仍然会返回它的this,因为构造函数总是返回一个对象,即使你试图返回其他东西。

如果Number 作为函数调用,它会进行类型转换。由于没有值传递给它(值val作为它的this对象传递,没有提供值),表达式返回 +0。

那有什么意义呢?您是否尝试创建一个值为 的 Number 对象val?你可能最好给Price.prototype自定义toStringvalueOf方法来返回适当的值。模仿Number.prototype的同名方法是有意义的。

> // Price.prototype = Number.prototype; 
> Price.prototype = new Number();
> // any difference?

[[Prototype]]是的,第二个在链上为 Price 实例添加了一个额外的 Number 对象。这意味着您可以在不影响 Number.prototype 的情况下向 Price.prototype 添加属性和方法。

这是一个示例实现:

function Price(value, symbol) {
  this.value = value;
  this.symbol = symbol;
}

Price.prototype = {
  toString: function() {
    return '' + this.symbol + this.valueOf();
  },

  valueOf: function() {
    return this.value.toFixed(2);
  }
}

var x = new Price(10.50, '$');

alert(x + '\n' + (1*x)); // $10.50  10.5
于 2012-06-09T14:31:51.137 回答