JavaScript数字继承

JavaScript数字继承,javascript,numbers,prototypal-inheritance,Javascript,Numbers,Prototypal Inheritance,假设我想用JS制作一个简单的Price类。它基本上是一个数字,所以我想我应该继承一个数字。下面是一些代码: Number.prototype.toMoney = function (precision, decimals, thousands) { // Formats number... } function Price(val) { Number.call(val); // Based on MozillaDN } Price.sufix = ' EUR'; // To

假设我想用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.

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

你这句话有错,我想:

Price.prototype - new Number(); // any difference?
您将分配一个新的数字作为Price的原型,因此需要使用=号而不是减号

应改为:

Price.prototype = new Number(); // any difference?
尽管如此,它仍然不起作用。我不明白你为什么要从数字继承

function Price(val) {
    Number.call(this, val);
}
这项工作:

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); 

您的构造函数没有执行您认为的操作:

function Price(val) {
    Number.call(val); // Based on MozillaDN
}
当作为构造函数调用时,上述函数将返回一个普通对象(函数的
this
对象),而不是
Number.call(val)
返回的值,该值是原语值+0,而与
val
的值无关。因此,即使您尝试返回它,构造函数仍然会返回它的this,因为构造函数总是返回一个对象,即使您尝试返回其他对象

如果是,则执行类型转换。由于未向其传递任何值(在未提供值的情况下,
val
的值作为其this对象传递),因此表达式返回+0

那又有什么意义呢?您正在尝试创建值为
val
的数字对象吗?您最好给出Price.prototype自定义toString和valueOf方法,以返回适当的值。模仿Number.prototype的相同命名方法是有意义的

> // Price.prototype = Number.prototype; 
> Price.prototype = new Number();
> // any difference?
是的,第二个为Price实例在
[[Prototype]]
链上添加了一个额外的Number对象。这意味着您可以向Price.prototype添加属性和方法,而不影响Number.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

当我为几乎相同的问题寻找答案时,我发现了这一页。由于这有助于我做出最后的结论,我喜欢与大家分享。从Number继承自己的对象确实是可能的

function Price(val) {
    Number.call(this, val);
}
这是您通常调用父对象构造函数的方式,但在本例中它不起作用,因为构造函数返回
val
本身。当您尝试读取
val
时,会收到“Number.prototype.valueOf不是泛型”错误

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));

仅供参考,它是
后缀
,而不是
sufix
Number.call()
看起来也有点奇怪-我认为你不能像那样调用构造函数。我认为这不会很好地工作,因为“Number.prototype.valueOf不是泛型的”。虽然您有权访问
Price
实例,但无法获取基本的数值。@pimvdb我已经在努力解决这个问题,但我认为这可能很困难。这是否意味着我应该忽略继承,在Price类中创建一个名为“value”的属性作为ex.?这个想法是正确的,但是如果出现“非泛型”错误,我想您继承本机函数可能会走运。您正在调用
Price
实例上的
Number
。你仍然没有一个真正的
Number
值,你可以在上面调用
valueOf
。顺便说一句,我想你的意思是
Number。调用(this,val)
Number
继承
Price
,但这两种方法都不起作用。对不起,这只是一个打字错误示例。