如何在 JavaScript 中重写 valueOf() 的行为作为 Number 的原型?

问题描述 投票:0回答:2

当我尝试覆盖此内容时出现错误:

Number.prototype.toString = function () {
  return "This is the number: " + this
};

Number.prototype.valueOf = function () {
  //console.log(this)
  return this;
}

console.log(new Number(33).toString());
console.log(new Number(34).valueOf())

Js 返回错误

RangeError: Maximum call stack size exceeded
,如何覆盖要返回的值,例如字符串 - 'The number is ${this}'

我发现,如果删除,一切都会正常工作

console.log(new Number(33).toString());

我尝试对此进行 console.log 并得到这样的输出: Code output

javascript numbers prototype prototypejs value-of
2个回答
0
投票

我真的不想给出这个建议,也不知道为什么你不会声明一个子

Class
,其原型设置为
Object.create(Number.prototype)
,但如果你想在所有数字上这样做,那么你可以去带有猴子补丁:

Number.prototype.toString = (function(f){return function(){return `whatever ${f.call(this)}`}})(Number.prototype.toString)

Number.prototype.valueOf = (function(f){return function(){return f.call(this)}})(Number.prototype.valueOf)

valueOf
toString
更改为您需要的任何内容。

警告:这不好。


0
投票

当使用

Number
创建
new
时,您创建了一个
Number object
,它不是原语 - 请参阅 MDN。这可能是错误的根源。

我认为有更好的方法来重写

Number
方法,而不污染其
prototype

其中之一是创建一个自定义

Number
对象,使用闭包来保存其值并使用一些函数扩展它。这样你就不需要
protoype
(或
this
)。比如:

function MyNr(nr = 0) {

  // the number function encloses [nr]
  const number = nrGiven => {
    nr = nrGiven;
  }
  
  const myNumberExtensions = {
    toString() { return `This is the number ${nr}`},
    set value(val) { nr = val; },
    clone(value) { return MyNr(value); },
    valueOf() { return nr; },
  };
  
  // because Function is just another object,
  // you can extend it with custom methods
  Object.entries(Object.getOwnPropertyDescriptors(myNumberExtensions))
    .forEach( ([key, descriptor]) => { 
      Object.defineProperty(number, key, descriptor); 
    }
  );
  
  return number;
}

const myNr1 = MyNr(33);
const myNr2 = myNr1.clone(42);

console.log(myNr1.toString());
// toString automatically when within a (template) string:
console.log(`${myNr1}`);

console.log(myNr2.valueOf());
// valueOf automatically when appended to a string
console.log(""+myNr2);

© www.soinside.com 2019 - 2024. All rights reserved.