Javascript 对象上的算术运算

Javascript 对象上的算术运算,javascript,Javascript,我正在查看一个现有的库,对在对象上使用算术运算感到困惑 用于算术运算的对象如下所示: { _high: 0, _low: 256, remainder: { _low: 0, high: 0, remainder: null } } const id = { _high: 0, _low: 256, remainder: { _low: 0, high: 0, remainder: null } }; while (id > 0) { const remai

我正在查看一个现有的库,对在对象上使用算术运算感到困惑

用于算术运算的对象如下所示:

{
  _high: 0,
  _low: 256,
  remainder: { _low: 0, high: 0, remainder: null }
}
const id = {
  _high: 0,
  _low: 256,
  remainder: { _low: 0, high: 0, remainder: null }
};

while (id > 0) {
  const remainder = Math.floor(id % 14);
}
它们的用途如下:

{
  _high: 0,
  _low: 256,
  remainder: { _low: 0, high: 0, remainder: null }
}
const id = {
  _high: 0,
  _low: 256,
  remainder: { _low: 0, high: 0, remainder: null }
};

while (id > 0) {
  const remainder = Math.floor(id % 14);
}
问题:

如果一个人对一个对象应用像模这样的算术运算,或者将其与一个数字进行比较,会发生什么

如果可能,将给定的代码段重写为使用对象属性的内容。

对象(和数组)将首先转换为它们的等价基元值,并根据刚才提到的ToNumber规则将结果值(如果基元不是一个数字)强制为一个数字

要转换为等效的原语值,TopPrimitive抽象操作(ES5规范,第9.1节)将参考有问题的值(使用内部DefaultValue操作-ES5规范,第8.12.8节),查看是否有valueOf()方法。如果valueOf()可用,并且它返回一个原语值,则该值将用于强制。如果没有,则toString()将提供强制的值(如果存在)

如果两个操作都不能提供原语值,则抛出TypeError


因此,我假设您的对象有一个
valueOf
方法,该方法返回一个数字,因此在您对对象执行的两个算术运算中,调用该方法将对象强制为一个数字,结果值就是操作中实际使用的值。


另外,您的示例是非常无用的,因为它没有包含基本的
valueOf
方法,当我们尝试执行类似
id+10
的操作时,会得到
[object]10
,这是为什么?的默认
值无法提供原语,因此会参考
toString
,返回
[object object]
,然后将原语值与
10
连接,从而产生
[object object]10

为了更好地理解这一点,请看以下示例:

1.


2

const id = {
_high: 0,
_low: 256,
remainder: { _low: 0, high: 0, remainder: null },
valueOf: function(){
return {}; // valueOf fails to provide a primitive
},
toString: function() {
return 10; // toString provides a primitive value, so "10" will be used.
}
};


console.log(id + 10); // prints out "20"

3

const id = {
_high: 0,
_low: 256,
remainder: { _low: 0, high: 0, remainder: null },
valueOf: function(){
return {}; /* valueOf fails to provide a primitive */
},
toString: function() {
return {}; /* toString fails to provide a primitive as well */
}
};


console.log(id + 10); // a "TypeError" is thrown :(
:

对象(和数组)将首先转换为它们的等价基元值,并根据刚才提到的ToNumber规则将结果值(如果基元不是一个数字)强制为一个数字

要转换为等效的原语值,TopPrimitive抽象操作(ES5规范,第9.1节)将参考有问题的值(使用内部DefaultValue操作-ES5规范,第8.12.8节),查看是否有valueOf()方法。如果valueOf()可用,并且它返回一个原语值,则该值将用于强制。如果没有,则toString()将提供强制的值(如果存在)

如果两个操作都不能提供原语值,则抛出TypeError


因此,我假设您的对象有一个
valueOf
方法,该方法返回一个数字,因此在您对对象执行的两个算术运算中,调用该方法将对象强制为一个数字,结果值就是操作中实际使用的值。


另外,您的示例是非常无用的,因为它没有包含基本的
valueOf
方法,当我们尝试执行类似
id+10
的操作时,会得到
[object]10
,这是为什么?
的默认
值无法提供原语,因此会参考
toString
,返回
[object object]
,然后将原语值与
10
连接,从而产生
[object object]10

为了更好地理解这一点,请看以下示例:

1.


2

const id = {
_high: 0,
_low: 256,
remainder: { _low: 0, high: 0, remainder: null },
valueOf: function(){
return {}; // valueOf fails to provide a primitive
},
toString: function() {
return 10; // toString provides a primitive value, so "10" will be used.
}
};


console.log(id + 10); // prints out "20"

3

const id = {
_high: 0,
_low: 256,
remainder: { _low: 0, high: 0, remainder: null },
valueOf: function(){
return {}; /* valueOf fails to provide a primitive */
},
toString: function() {
return {}; /* toString fails to provide a primitive as well */
}
};


console.log(id + 10); // a "TypeError" is thrown :(
答:调用了方法.valueOf() 您可以在那里实现自己的逻辑

var obj={
a:11,
b:30,
valueOf:函数(){
返回这个.a+这个.b;
}
}
如果(obj>40){
警报(obj+1);
}
回答:调用方法.valueOf() 您可以在那里实现自己的逻辑

var obj={
a:11,
b:30,
valueOf:函数(){
返回这个.a+这个.b;
}
}
如果(obj>40){
警报(obj+1);

}
@NinaScholz查看评论。它将返回一个类似上面给定示例的对象。@NinaScholz这正是我的问题,我也不明白,但它是有效的。你可以自己测试。我注意到,如果(all?)属性为0(null?),它将返回false;如果一个数字(例如:
\u low
大于0),JavaScript将通过调用
.valueOf()
方法尝试将对象转换为一个数字,它将返回true。这在语言规范中有详细的解释。@NinaScholz将调用
.valueOf
并使用它返回的内容;在本例中,它返回一个对象。当然,发布的代码在任何意义上都不“起作用”。@Taurus是大于运算符和小于运算符(
@NinaScholz查看注释。它将返回一个与上述示例类似的对象。@NinaScholz这正是我的问题,我也不明白,但它可以工作。您可以自己测试它。我注意到,如果(所有?)属性为0(和null?),它将返回false,如果有一个数字,它将返回true(例如:
\u low
大于0)JavaScript将尝试通过调用
.valueOf()
方法将对象转换为数字。这在语言规范中有详细解释。@NinaScholz将调用
.valueOf
并使用它返回的内容;在这种情况下,它返回一个对象。发布的代码不“工作”当然在任何意义上。@Taurus是大于运算符和小于运算符(
但一般来说,基于将对象强制转换为字符串或数字来构建流是个坏主意;更好的方法是将适当的逻辑移到一些命名良好的方法,如
if(obj.isStillAlive())…
我同意,但必须这样做