You Don't Know JS: types & grammar, chapter 4:
Objects (und Arrays) wird zunächst auf ihren Grundwert Äquivalent umgewandelt werden, und der resultierende Wert (wenn ein primitiver nicht aber bereits eine Nummer) zu einer Reihe gezwungen wird entsprechend der ToNumber gerade erwähnte Regeln.
Um in diese primitive Wertäquivalent zu konvertieren, wird die ToPrimitive abstrakte Operation (ES5-Spezifikation, Abschnitt 9.1) den fraglichen Wert konsultieren (unter Verwendung der internen DefaultValue-Operation-ES5-Spezifikation, Abschnitt 8.12.8), um zu sehen, ob es a hat valueOf() -Methode. Wenn valueOf() verfügbar ist und einen primitiven Wert zurückgibt, wird dieser Wert für die Nötigung verwendet. Wenn nicht, liefert toString() den Wert für die Nötigung, falls vorhanden.
Wenn keine der beiden Operationen einen primitiven Wert bereitstellen kann, wird ein TypeError ausgelöst.
Also, ich gehe davon aus, dass das Objekt ein valueOf
Methode hat, die eine Zahl zurückgibt, so in beiden arithmetischen Operationen, die Sie auf Ihrem Objekt durchführen, diese Methode aufgerufen wird, um das Objekt in eine Reihe zu zwingen, und der resultierende Wert ist, was tatsächlich in der Operation verwendet wird.
Auch Ihr Beispiel ziemlich nutzlos ist, da es nicht, dass die zugrunde liegenden
valueOf
Verfahren nicht enthalten, wenn wir versuchen, so etwas wie
id + 10
zu tun, wir
[object Object]10
bekommen, warum ist das so? Der Standardwert
valueOf
ist nicht in der Lage, ein Grundelement bereitzustellen, also wird
toString
abgefragt, das
[object Object]
zurückgibt. Dieser Grundelementwert wird dann mit
10
verkettet, was zu
[object Object]10
führt.
Um dies besser zu verstehen, einen Blick auf diese Beispiele nehmen:
1.
const id = {
_high: 0,
_low: 256,
remainder: { _low: 0, high: 0, remainder: null },
valueOf: function(){
return 20; /* valueOf does not fail to provide a primitive, "20" will
be used". */
},
toString: function() {
return 10; /* toString's return value would be used (if it was a primitive), if "valueOf" failed to provide a primitive. */
}
};
console.log(id + 10); // prints out "30"
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 :(
@NinaScholz Siehe den kommentar. Es würde ein Objekt wie das obige Beispiel zurückgeben. – kentor
@NinaScholz Das ist genau meine Frage, ich verstehe es auch nicht, aber es funktioniert. Sie können es selbst testen. Ich bemerkte, dass es false zurückgab, wenn (alle?) Eigenschaften 0 sind (und null?) Und es wird true zurückgeben, wenn eine Zahl (zB: _low' höher als 0 ist) – kentor
JavaScript wird versuchen, das Objekt zu konvertieren eine Zahl durch Aufruf der '.valueOf()' Methode. Das wird detailliert in der Sprachspezifikation erklärt. – Pointy