提问人:yarslvd 提问时间:11/16/2023 最后编辑:yarslvd 更新时间:11/17/2023 访问量:97
如何在 JavaScript 中覆盖 valueOf() 作为 Number 原型的行为?
How can I override the behavior of valueOf() as a prototype of the Number in JavaScript?
问:
我的任务是了解 .toString 和 .valueOf 方法、谁调用它们、在哪里使用它们、它们如何工作、如何调用以及如何更改调用顺序。
当我尝试覆盖它时,我收到一个错误:
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返回错误,如何覆盖值返回,例如字符串 - 'The number is ${this}'RangeError: Maximum call stack size exceeded
我发现如果我删除,一切正常console.log(new Number(33).toString());
我试图控制台.log这个并得到这样的输出:代码输出
答:
1赞
ibrahim tanyalcin
11/16/2023
#1
我真的不想给出这个建议,也不知道为什么你不声明一个将其原型设置为的潜艇,但如果你想在所有数字上这样做,那么你可以使用猴子补丁: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)
将 AND 更改为您需要的任何内容。valueOf
toString
警告:这不好。
评论
0赞
yarslvd
11/17/2023
非常感谢!我知道最好不要覆盖这些方法,但这是我的任务。另外,我还有一个问题。我们覆盖了这些方法,它们仅适用于使用构造函数(new Number(10))创建的数字,对吗?我们是否有机会改变在隐式转换过程中以文字形式表示的数字的行为?
1赞
Pointy
11/17/2023
@yarslvd当你编写类似的东西时,(数字原语)会自动转换为数字实例。(17).valueOf()
17
0赞
yarslvd
11/17/2023
@Pointy,是的,我理解这一点,但是,例如,如果 console.log(“3” + myNum),在这种情况下数字是“const myNum = 10”,那么数字如何转换为字符串?
0赞
Pointy
11/17/2023
@yarslvd,每当将数字转换为字符串时,都会调用该方法。.toString()
0赞
yarslvd
11/17/2023
@Pointy 但是,当我们使用数字的文字表达式时,为什么不使用我们的重写方法呢?.toString()
0赞
KooiInc
11/16/2023
#2
创建 using 时,您将创建一个 Number 对象,该对象
不是原语 - 请参阅 MDN。这可能是错误的根源。Number
new
我认为有更好的方法可以覆盖方法,而不会污染其.Number
prototype
例如,创建一个自定义对象,使用闭包来保存其值,并使用某些函数扩展它。这样你就不需要(或就此而言)。像这样:Number
protoype
this
function XNumber(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 XNumber(value ?? nr); },
increment(withValue = 1) { nr += withValue; return number; },
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 = XNumber(41);
const myNr2 = myNr1.clone().increment();
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);
评论
0赞
Pointy
11/16/2023
并不是说我同意修改 Number 原型,但有一个功能是表达式会自动选择修改后的方法。(x * 2).toString()
0赞
KooiInc
11/16/2023
@Pointy当然,一切都有代价; 不过会起作用。XNumber(x*2).toString()
0赞
yarslvd
11/17/2023
谢谢,但我有一个确切的任务来覆盖这些方法以了解 JS 的工作原理)
评论
toString
this