【问题标题】:Is there a way of having arithmetic operators use getters and setters in Javascript ES6?有没有办法让算术运算符在 Javascript ES6 中使用 getter 和 setter?
【发布时间】:2020-01-26 04:41:54
【问题描述】:

我有一个基本的 ID 系统,其中一个数字被转换为一个字符串并用零填充至少 3 位数字。只要我只使用常规作业,它就可以正常工作。有没有办法让算术运算符也与 setter 一起使用?

class Test {
  constructor() {
    this.id = 0;
  }

  /**
   * @param {Number} num
   */
  set id(num) {
    if (num < 10) {
      this._id = '00' + num;
    } else if (num < 100) {
      this._id = '0' + num;
    } else {
      this._id = '' + num;
    }
  }

  get id() {
    return this._id;
  }

  incrementID(increment=1) {
    const id = parseInt(this.id);
    this.id = id + increment;
  }
}

const test = new Test();
test.id = 5;
console.log(`ID is: ${test.id}`); // ID is: 005

test.id += 5;
console.log(`ID is: ${test.id}`); // ID is: 00055 (How?!?)

我知道我可以有一个像我写的那样的 incrementID 方法,但感觉这违背了 ES6 setter 和 getter 的理念。

作为旁注,加法分配甚至发生了什么?如果有什么奇怪的话,我预计结果会是 0055,因为它是一个被添加到字符串中的数字。

【问题讨论】:

  • 根据您的逻辑,“005”+ 5 变成“0055”,因为数字是 55,小于 100,在前面加上“0”,然后变成“00055”。字符串转换是你的问题。
  • 不,没有办法避免这种情况,只能有一个数字 .id 属性和一个 单独 paddedId 字符串获取器。

标签: javascript getter-setter assignment-operator es6-class


【解决方案1】:

嗯,理论上你可以将 'id' 设为一个对象,并提供一个钩子将其默认转换为数字:

class ID {
    constructor(value) {
        this.value = value;
    }

    [Symbol.toPrimitive](hint) {
        if (hint === 'number' || hint === 'default')
            return Number(this.value)
        return String(this.value);
    }
}

class Test {
    constructor() {
        this.id = new ID('000');
    }

    set id(num) {
        let s;
        if (num < 10) {
            s = '00' + num;
        } else if (num < 100) {
            s = '0' + num;
        } else {
            s = '' + num;
        }
        this._id = new ID(s);

    }

    get id() {
        return this._id;
    }
}


const test = new Test();
test.id = 5;
console.log(`ID is: ${test.id}`); // ID is: 005

test.id += 5;
console.log(`ID is: ${test.id}`); // ID is: 010

Docs

也就是说,一种实用的方法是拥有两个属性(数字和格式化字符串),如上所述。

【讨论】:

    【解决方案2】:

    你的 getter 和 setter 正在被使用。这就是正在发生的事情。

    testid += 5;
    

    被翻译成

    test.id = test.id + 5
    

    这首先调用getter,它返回"005"。然后它连接5,得到"0055"。所以相当于:

    test.id = "0055";
    

    在 setter 中,它进入了这个测试:

    if (num < 100)
    

    这是真的,因为 55 小于 100。确实如此:

    this._id = '0' + num;
    

    这会将0 连接到前面,因此它分配了"00055"

    您可以通过让 getter 首先将 num 转换为整数来解决此问题。

      set id(num) {
        num = parseInt(num);
        if (num < 10) {
          this._id = '00' + num;
        } else if (num < 100) {
          this._id = '0' + num;
        } else {
          this._id = '' + num;
        }
      }
    

    但是没有办法让+= 在进行增量之前将字符串转换为数字。 getter 不知道您将如何使用该值,当属性是增量操作的一部分时,它不能返回不同的东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-09
      • 1970-01-01
      • 2019-06-26
      • 2021-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多