javascript - Number 的子类永久转换回内置 Number 对象/函数

标签 javascript class javascript-objects prototype prototype-programming

为了不污染或扩展原型(prototype) Number 对象,我尝试创建一个扩展 Number 的类。但是,当我执行此操作然后尝试向其中添加任何内容甚至将其添加到自身时,它会被转换回数字。

我知道发生这种情况是因为它采用数字 valueOf 属性值并将该值添加到另一个数字中返回,但我希望该值始终保留其子类,而无需创建额外的方法如下:

  • .add(x)
  • .sub(x)
  • .mul(x)
  • .div(x)

有没有一种方法可以实现这一点,类似于 NumberBigInt 类型允许这些类型的计算?我可以(但不想)扩展内置 Number 对象来支持我的自定义方法,但现在每当我尝试使用它们时,它们都会丢失所有方法。

例如:

let num = 5;
console.log(num.constructor); // Number
num += 2;
console.log(num); // 7
console.log(num.constructor); // still Number

但是,使用我的扩展类:

class MyNum extends Number {
    constructor (num = 0) {
        super(num);
    }
    get isEven() { return this.isInt && this % 2 === 0 }
    get isOdd() { return this.isInt && this % 2 !== 0 }
}
let num = new MyNum(5);
console.log(num.constructor); // MyNum
num += 2;
console.log(num); // 7
console.log(num.constructor); // back to Number

此外,如果这里唯一的解决方案是添加像 .add(x) 这样的方法,那么每当像 .add(x)< 这样的计算时,我是否需要重新创建一个新的类实例 已完成,或者是否有另一种更原生的方式来添加现有对象的值。

如果以下是唯一的解决方法,我可能会坚持扩展内置的 Number 对象:

class MyNum extends Number {
    constructor (num = 0) {
        super(num);
    }
    add(x) { return new MyNum(this.valueOf() + x) }
    sub(x) { return new MyNum(this.valueOf() - x) }
    mul(x) { return new MyNum(this.valueOf() * x) }
    div(x) { return new MyNum(this.valueOf() / x) }
    mod(x) { return new MyNum(this.valueOf() % x) }
    get isEven() { return this.isInt && this % 2 === 0 }
    get isOdd() { return this.isInt && this % 2 !== 0 }
}

最佳答案

如果你愿意

num += 2;

导致num之前是一个MyNum,之后是一个MyNum,恐怕这是不可能的。如the specification也就是说,所有值都将转换为基元(valueOftoString),之后将基元连接在一起或相加 - 并且将导致基元的连接或添加以普通原语作为结果,可以是字符串、数字或 BigInt。

添加新的显式方法(例如 .add)是唯一真正的选择。

数字对象的值为 in an internal slot这是不可改变的(无论如何你也不想改变,因为突变可能会令人困惑)。我认为没有比 add(x) { return new MyNum(this.valueOf() + x) } 等更好的方法了。但是您可以通过删除 来稍微清理您的方法>valueOf 调用,不需要它们。

add(x) { return new MyNum(this + x) }
sub(x) { return new MyNum(this - x) }

关于javascript - Number 的子类永久转换回内置 Number 对象/函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68277559/

相关文章:

javascript - 只获取在javascript中构造成字符串的文本节点

javascript - 内容脚本未收到我发送的对象

javascript - 如何在 Javascript 中读取 JSON(服务器响应)?

class - 如何使用 Roxygen2 正确记录 S4 类插槽?

Java创建多个内部类对象并拥有自己的实例

javascript - 搜索对象数组并在值与字符串或子字符串匹配时返回整个对象

javascript - 使用 jQuery 更改动态生成元素的背景颜色

R R6 类和 UseMethod/泛型方法

javascript - 如何读取/访问名称 :values of Objects stored within an Array?

JavaScript 递归 setTimeout