有没有办法让算术运算符在 Javascript ES6 中使用 getter 和 setter?
Is there a way of having arithmetic operators use getters and setters in Javascript ES6?
我有一个基本的 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 setters 和 getters 的哲学。
作为旁注,加法作业甚至发生了什么?如果有什么奇怪的话,我会期望结果是 0055
,因为它是一个被添加到字符串中的数字。
好吧,理论上您可以使 '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
也就是说,一种实用的方法是拥有两个属性(数字和格式化字符串),如上文所建议。
您的 getter 和 setter 正在使用中。这是正在发生的事情。
testid += 5;
翻译成
test.id = test.id + 5
这首先调用了 getter,其中 return 是 "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 不知道您将如何使用该值,当 属性 是增量操作的一部分时,它不能 return 有什么不同。
我有一个基本的 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 setters 和 getters 的哲学。
作为旁注,加法作业甚至发生了什么?如果有什么奇怪的话,我会期望结果是 0055
,因为它是一个被添加到字符串中的数字。
好吧,理论上您可以使 '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
也就是说,一种实用的方法是拥有两个属性(数字和格式化字符串),如上文所建议。
您的 getter 和 setter 正在使用中。这是正在发生的事情。
testid += 5;
翻译成
test.id = test.id + 5
这首先调用了 getter,其中 return 是 "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 不知道您将如何使用该值,当 属性 是增量操作的一部分时,它不能 return 有什么不同。