Object to Primitive Conversion

JavaScript Object to Primitive Conversion (JavaScript对象到基元转换)

Now it’s time to find out what will happen if you add objects obj1 + obj2, subtract obj1 - obj2, or print using alert(obj). In such a case, objects will be auto-converted to primitives, after which the operation will be carried out. Here are the main rules for numeric, string, and boolean conversions of objects:

  • Overall objects are considered true in a boolean conversion. There are merely string and numeric conversions. (-在布尔转换中,整体对象被认为是true。只有字符串和数字转换。)

  • The numeric conversions take place when subtracting objects or applying mathematical functions. (-数值转换发生在减去对象或应用数学函数时。)

  • String conversion happens when we output an object like alert(obj) and in contexts like that. (-当我们输出像alert (obj)这样的对象以及类似的上下文时,会发生字符串转换。)

ToPrimitive

ToPrimitive (至主要)

It is possible to enhance string and numeric conversion. To meet that goal, you need to use unique object methods. (可以增强字符串和数字转换。为了实现这一目标,您需要使用独特的对象方法。)

We observe three variants of type conversion, also known as “hints” that are described in specification:

“string”

In case of an object-to-string conversion, while operating on an object which expects a string, like alert:

// output
alert(obj);

// using object as a property key
anotherObj[obj] = 120;

“number” (编号)

In case of an object-to-number conversion, like when you are doing mathematics:

// explicit conversion
let num = Number(obj);
// maths (except binary plus)
let n = +obj; // unary plus
let delta = obj1 - obj2;
// less/greater comparison
let greater = obj1 > obj2;

“default” (默认)

It happens rarely, in case the operator doesn’t certainly know which type to expect. For example, the binary + will work with both numbers and strings. If the binary + has an object as an argument, it will use the “default” for converting it. (这种情况很少发生,以防操作员不确定应该期待哪种类型。 例如,二进制+将与数字和字符串一起使用。 如果二进制+有一个对象作为参数,它将使用“默认”来转换它。)

When you compare object using == with a symbol, number, or a string, it is not clear which conversion is better to do. That’s why it is better to use the “default” hint. (当您使用= =与符号、数字或字符串比较对象时,不清楚哪种转换更好。这就是为什么最好使用“默认”提示。)

// binary plus uses the "default" hint
let total = obj1 + obj2;

// obj == number uses the "default" hint
if (car == 1) { ...
};

The greater and less comparison operators <, > work with numbers and strings as well. But, note that in this case, the “number” hint is used, not the “default”, as in the previous examples.

Anyway, in practice, you don’t need to remember all these details, almost all built-in objects ( the exception is the Date object ). (无论如何,在实践中,您不需要记住所有这些细节,几乎所有内置对象(例外是Date对象)。)

For implementing the conversion, JavaScript needs to find and invoke 3 object methods. They are as follows:

  • Call objSymbol.toPrimitive - a method including a symbolic key Symbol.toPrimitive. If there are such methods, (-调用obj [Symbol.toPrimitive] (提示) -一种包含符号键Symbol.toPrimitive的方法。如果有这样的方法,)

  • In other cases, when the hint is “string”, keep on trying obj.toString() and obj.valueOf(). (-在其他情况下,当提示为“string”时,继续尝试obj.toString ()和obj.valueOf ()。)

  • If the hint is “default” or “number”, keep on trying obj.valueOf() and obj.toString(). (-如果提示为“default”或“number” ,请继续尝试obj.valueOf ()和obj.toString ()。)

Symbol.toPrimitive

Symbol.toPrimitive

The first thing that you should know is that a built-in method exists known as Symbol.toPrimitive. In general, you can use it for naming your conversion method as follows:

obj[Symbol.toPrimitive] = function (hint) {
 // must return a primitive value
(//必须返回一个基元值)
 // hint = one of "string", "number", "default"
};

In the following example, car object applies it:

let car = {
 name: "BMW",
 price: 30000,
 [Symbol.toPrimitive](hint) {
   console.log(`hint: ${hint}`);
   return hint == "string" ? `{name: "${this.name}"}` : this.price;
 }
};
// conversions demo:
console.log(car); // hint: string -> {name: "BMW"}
console.log(+car); // hint: number -> 30000
console.log(car + 5000); // hint: default -> 35000

toString/valueOf

toString/valueOf

Now it’s time to learn about toString and valueOf methods. Don’t get surprised to find out that they are not considered as symbols. They are among the most ancient methods. (现在是时候了解toString和valueOf方法了。不要惊讶地发现它们不被视为符号。它们是最古老的方法之一。)

The primary purpose of these methods is to provide an “ancient-style” way to run the conversion. (这些方法的主要目的是提供一种“古老风格”的转换方式。)

In the event of not existing Symbol.toPrimitive JavaScript will try to find them in the following sequence:

toString -> valueOf in case of “string” hint. valueOf -> toString in other cases (toString - > valueOf (在“string”提示的情况下)。 在其他情况下, valueOf - > toString)

The methods mentioned above will bring a primitive value. Returning an object by valueOf or toString means that it is ignored. (上述方法将带来一个原始值。通过valueOf或toString返回对象意味着它被忽略。)

An object includes toString and valueOf methods as follows:

  • “[object Object]” is returned by the method of toString. (- “[object Object]”由toString方法返回。)

  • The object itself will be returned by the valueOf method. (-对象本身将由valueOf方法返回。)

Let’s have a look at this case:

let site = {
 name: "w3cdoc"
};
console.log(site); // [object Object]
console.log(site.valueOf() === site); // true

Therefore, anytime using an object as a string, you will have [object Object]. (因此,无论何时使用对象作为字符串,您都将拥有[object Object]。)

The Types of Return

The Types of Return (退货类型)

First and foremost, you need to note that primitive-conversion methods never return the primitive that was hinted. You can’t control whether toString method returns a string or Symbol.toPrimitive returns “number”. (首先,您需要注意,原语转换方法永远不会返回提示的原语。无法控制toString方法是返回字符串,还是Symbol.toPrimitive返回"number"。)

One thing is compulsory: the methods mentioned above have to return a primitive and never an object.

Further Conversions

Further Conversions (进一步转化)

You have already learned that a wide range of operators and functions implement type conversions. For example, multiplying * will convert operands into numbers. (您已经了解到,各种运算符和函数都实现了类型转换。例如,乘以*将操作数转换为数字。)

In the event of passing an object as an argument, two stages can be distinguished:

  • The object has been converted to a primitive. (-对象已转换为基元。)

  • In case the resulting primitive isn’t of the proper type, it is converted. (-如果生成的图元类型不正确,则将其转换。)

Let’s have a look at this example:

let obj = {
 //toString is capable of handling all conversions in the absence of different methods
(//toString能够在没有不同方法的情况下处理所有转换)
 toString() {
   return "2";
 }
};
console.log(obj * 3); // 6, the object is converted to primitive "2", after which a number is made by multiplication

Here, as the first step, the object is converted to a primitive by the multiplication obj * 3. Afterward, “2” * 3 is transformed into 2 * 3. (这里,作为第一步,乘法obj * 3将对象转换为原语。然后将“2” * 3转化为2 * 3。)

Strings will be concatenated in the same condition by the binary plus as it accepts a string. Here is an example:

let obj = {
 toString() {
   return "2";
 }
};
console.log(obj + 3); // 23 ("2" + 3), the object is converted to primitive  returned a string => concatenation

Summary

Summary (概要)

The conversion from object to primitive can be invoked automatically by a range of built-in functions and operators expecting primitive as a value. (从对象到基元的转换可以由一系列内置函数和期望基元作为值的运算符自动调用。)

It has the following three hints:

“string” used for alert as well as other operations that require a string; “number” (used for mathematics) “default”( not many operators)

The algorithm of the conversion is as follows:

Run objSymbol.toPrimitive in case there is a method In other cases, when the hint is “string” (在有方法的情况下运行obj [Symbol.toPrimitive] (hint) 在其他情况下,当提示为“string”时) . run obj.toString() and obj.valueOf(), whichever exists In case the hint is “default"or “number” (. run obj.toString ()和obj.valueOf () ,以存在者为准 如果提示是“默认”或“数字”) . run obj.valueOf() and obj.toString(), whichever exists. (.运行obj.valueOf ()和obj.toString () ,以存在者为准。)



请遵守《互联网环境法规》文明发言,欢迎讨论问题
扫码反馈

扫一扫,反馈当前页面

咨询反馈
扫码关注
返回顶部