实现 (5).add(3).minus(2) 功能

通过扩展 Number 原型实现链式调用的加减运算功能

问题

这道题要求我们实现一个功能,使得数字可以直接调用 add()minus() 方法进行加减运算,并且支持链式调用。例如 (5).add(3).minus(2) 应该返回 6。

这需要我们扩展 JavaScript 的 Number 类型,为其添加自定义方法,同时保证方法返回值仍然是 Number 类型以支持链式调用。

解答

// 方法一:扩展 Number 原型
Number.prototype.add = function(num) {
  // this 指向调用该方法的数字
  // 返回新的数字以支持链式调用
  return this + num;
};

Number.prototype.minus = function(num) {
  // 执行减法运算
  return this - num;
};

// 方法二:使用 Object.defineProperty(更规范)
Object.defineProperty(Number.prototype, 'add', {
  value: function(num) {
    return this.valueOf() + num;
  },
  enumerable: false, // 不可枚举,避免影响 for...in 循环
  writable: true,
  configurable: true
});

Object.defineProperty(Number.prototype, 'minus', {
  value: function(num) {
    return this.valueOf() - num;
  },
  enumerable: false,
  writable: true,
  configurable: true
});

使用示例

// 基本使用
console.log((5).add(3).minus(2)); // 输出: 6

// 复杂链式调用
console.log((10).add(5).minus(3).add(8).minus(2)); // 输出: 18

// 使用变量
const num = 100;
console.log(num.add(50).minus(30)); // 输出: 120

// 支持小数运算
console.log((3.5).add(2.5).minus(1)); // 输出: 5

// 支持负数
console.log((-5).add(10).minus(3)); // 输出: 2

// 可以与其他数字方法结合
console.log((5).add(3).minus(2).toFixed(2)); // 输出: "6.00"

关键点

  • 原型扩展:通过 Number.prototype 为所有数字类型添加方法,使得任何数字都可以调用这些方法

  • this 指向:在原型方法中,this 指向调用该方法的数字对象,可以直接参与运算

  • 返回值类型:方法必须返回 Number 类型,这样才能继续链式调用其他方法

  • valueOf() 方法:使用 this.valueOf() 可以获取数字的原始值,在某些场景下更加严谨

  • enumerable 属性:使用 Object.defineProperty 时设置 enumerable: false,避免自定义方法在 for...in 循环中被遍历出来

  • 注意事项

    • 修改原生对象原型在生产环境中需谨慎使用,可能会与其他库冲突
    • 可以考虑使用工具函数或类的方式实现,避免污染全局原型
    • 数字字面量需要用括号包裹,如 (5).add(3),否则会产生语法错误