ToPrimitive abstract operation in the ECMAScript7 specification

The core of converting a reference type to an original type is actually this internal abstraction method

1、Symbol — @@toPrimitive

Symbol has many famous symbols, @@toPrimitive, also known as symbol. toPrimitive, which is a property defined on the Symbol object.

2, ToPrimitive(input [, PreferredType])

The abstract operation takes an input parameter and an optional PreferredType parameter. The purpose of this abstract operation is to convert the input parameter to a non-object data type, that is, a primitive data type. If the input can be converted to multiple raw data at the same time, the value of the PreferredType is referred to. Refer to the following table for the transformation process:

parameterinputData type of The results of
Undefined Return input itself
Null Return input itself
Boolean Return input itself
Number Return input itself
String Return input itself
Symbol Return input itself
Object Perform the following steps
ifinputIs an object, perform the following steps:
  1. If it doesn’t come inPreferredTypeParameters,hintIs equal to the"default";
  2. ifPreferredTypeishint StringAnd lethintIs equal to the"string";
  3. ifPreferredTypeishint NumberAnd lethintIs equal to the"number";
  4. letexoticToPrimIs equal to theGetMethod(input, @@toPrimitive)Presumably semantics is getting parametersinputthe@@toPrimitiveMethods;
  5. ifexoticToPrimnotUndefined, then:
    1. letresultIs equal to theCall(exoticToPrim, input, « hint »)Semantics, presumably, is executionexoticToPrim(hint);
    2. ifresultIs the original data type and returnsresult;
    3. Throws an exception of the wrong type;
  6. ifhintis"default"And lethintIs equal to the"number";
  7. returnOrdinaryToPrimitive(input, hint)The result of an abstract operation.

Conclusion:

  1. Judge PreferredType,As long as the value passed is notstring, finally unified countnumber`
  2. @@toPrimitiveMethod priority is higher thanOrdinaryToPrimitive(input, hint)If the former can return the original type then you don’t need to do anything else
  3. if@@toPrimitiveMethod does not exist or returns a value that is not the original type, continue executionOrdinaryToPrimitive(input, hint)operation

Question: What is hint? How? (Read on)

3, OrdinaryToPrimitive (O, hint)

The data type of O is an object, the data type of hint is a string, and the value of hint is either “string” or “number”. The steps of this abstract operation are as follows:

  1. ifhintis"string"And letmethodNamesIs equal to the« "toString", "the valueOf" »;
  2. ifhintis"number"And letmethodNamesIs equal to the« "the valueOf", "toString" »;
  3. Iterate through the list in ordermethodNames, for each iteration valuename:
    1. letmethodIs equal to theGet(O, name)Presumably the semantics are getting objectsOthenameThe attribute corresponding to the value;
    2. ifmethodCan be called, then:
      1. letmethodIs equal to theCall(method, O)Semantics, presumably, is executionmethod();
      2. ifresultIs not an objectresult;
  4. Throws an exception of the wrong type.

According to the above steps:

  • throughToPrimitiveThe steps of6You can see that no optional parameter is providedPreferredTypeThe time,hintWill default to"number";
  • throughToPrimitiveThe steps of4You can define it@@toPrimitiveMethod to override default behavior, such as those defined in the specificationDateDate object andSymbolThe symbol object is defined on the prototype@@toPrimitiveMethods.

Conclusion:

  1. ifhintis"string"To performtoStringIf no original value is returned, the execution continuesvalueOfmethods
  2. ifhintis"number"To performvalueOfIf no original value is returned, the execution continuestoStringmethods

4, hint

Hint can be interpreted as automatically deciding whether to convert to string or number based on the scenario. If you cannot determine which one to convert to, the hint is default. Let’s simulate the process of getting the HINT value during the transformation

const obj = { 
    [Symbol.toPrimitive](hint) { 
        console.log(`hint: ${hint}`); }};const arr = []
arr[obj]
// hint: string 
Copy the code
const obj = { 
    [Symbol.toPrimitive](hint) { 
        console.log(`hint: ${hint}`); }}; -obj// hint: number
Copy the code
var a = [1.2.3]
a[Symbol.toPrimitive] = function (hint) {
    console.log(`hint: ${hint}`);
}
' ' + a
// hint: default

Copy the code

5. Conclusion:

If @@toprimitive (input, hint) returns the original type, no further operations are required

2. Determine the hint value

3. If hint is “string”, execute toString first; if no original value is returned, continue with valueOf

4. If hint is “number”, execute valueOf first; if no original value is returned, continue toString

There is also the last article, combined with a large number of topics to reflect the content mastered in the first two sections, will be more feeling

Reference: segmentfault.com/a/119000001…