微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Number 的子类持续转换回内置的 Number 对象/函数

如何解决Number 的子类持续转换回内置的 Number 对象/函数

为了不污染或扩展原型 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 所说,所有值都将转换为基元 (valueOf,toString),之后基元要么连接在一起,要么相加 - 并且基元的连接或相加将导致以普通原语作为结果,可以是字符串、数字或 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) }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。