When reading The column of “Relearning the front End” by Winter Big guy, I reviewed JS’s “unpacking conversion”. “Packing conversion” and “unpacking conversion” before are understood, today, their so-called understanding is really a little knowledge. After reading the content written by Teacher Winter, I am still not clear about the knowledge point of “unpacking conversion”, so I go to have a further understanding. Please refer to the “Reference link” at the end of this article for reference.

That we ignore

First, let’s look at an example:

const a = {
    name: 'a',
    toString () {
        console.log(this);
        console.log('toString');
        return { name: 'toString' };
    },
    valueOf () {
        console.log(this);
        console.log('valueOf');
        return { name: 'valueOf'}; }}; a *2;
// {name: "a", toString: ƒ, valueOf: ƒ}
// valueOf
// {name: "a", toString: ƒ, valueOf: ƒ}
// toString
// Uncaught TypeError: Cannot convert object to primitive value

a + "";
// {name: "a", toString: ƒ, valueOf: ƒ}
// valueOf
// {name: "a", toString: ƒ, valueOf: ƒ}
// toString
// Uncaught TypeError: Cannot convert object to primitive 

alert(a);
// {name: "a", toString: ƒ, valueOf: ƒ}
// toString
// {name: "a", toString: ƒ, valueOf: ƒ}
// valueOf
// Uncaught TypeError: Cannot convert object to primitive value
Copy the code

As you can see, toString and valueOf are not executed in a fixed order. Instead, they are executed according to some condition. When the ToPrimitive inner function of an object is called during an unboxed conversion, it automatically passes in a conversion type parameter, temporarily named Hint, depending on the execution context.

ToPrimitive

In the JavaScript standard, the ToPrimitive function is the implementer of the conversion from object type ToPrimitive type (i.e., unboxing conversion); But this is an internal algorithm, a set of rules that programming languages follow when executed internally.

The conversions of objects to String and Number follow the “unboxing before converting” rule. Unboxing converts an object to a primitive type and then converts it to a String or Number.

However, the internal implementation of the unboxing transformation varies for different operations, as shown in the example above.

The call rules and order of “unboxing transformation” are as follows:

  1. Check if any objects are explicitly defined by the user[Symbol.toPrimitive]Method, if any, is called directly;
  2. If not, the original internal function is executedToPrimitiveAnd then judge the incominghintValue if its value isstring, which calls objects sequentiallytoStringvalueOfMethods (wheretoStringThe method must be executed, returning and terminating if it returns a value of primitive type, or continuing otherwisevalueOfMethods);
  3. If you judge incominghintValues are not forstring, then it may benumberordefaultObject is called sequentiallyvalueOftoStringMethods (wherevalueOfThe method must be executed, returning and terminating if it returns a value of primitive type, or continuing otherwisetoStringMethods);

Let’s look at the first case:

const b = {
    [Symbol.toPrimitive] (hint) {
        console.log(`hint: ${hint}`);
        return {};
    },
    toString () {
        console.log('toString');
        return 1;
    },
    valueOf () {
        console.log('valueOf');
        return 2; }}; alert(b);// hint: string 
b + ' '; // hint: default
b + 500; // hint: default
+b; // hint: number
b * 1; // hint: number
Copy the code

The second and third cases:

const c = {
    toString () {
        console.log('toString');
        return 1;
    },
    valueOf () {
        console.log('valueOf');
        return 2; }}; alert(c);// Prints toString and alert 1
c + ' ';  // Print valueOf, "2"
c + 500; // Print valueOf, 502
+c; // Print valueOf, 2
c * 1; // Print valueOf, 2
Copy the code

So what do you mean by the three values hint takes? And what value does that correspond to?

determinehintThe values

String When we want a string operation, that is, an object-to-string conversion, we pass in the internal function ToPrimitive as string:

// output
alert(obj);

// using object as a property key
anotherObj[obj] = 123;
Copy the code

ToPrimitive = number; ToPrimitive = number; ToPrimitive = number;

// explicit conversion
let num = Number(obj);

// maths (except binary plus)
let n = +obj; // unary plus
let delta = date1 - date2;

// less/greater comparison
let greater = user1 > user2;
Copy the code

Default In some scenarios where it is not clear what base type the object needs to be converted to, the parameter value passed to the internal function ToPrimitive is default:

// binary plus
let total = car1 + car2;

// obj == string/number/symbol
if (user == 1) {... };Copy the code

conclusion

If dear readers find any errors or disagreements in this article, please leave a comment, discuss them together, and address the hidden and obscure points together.

Refer to the link

  • Relearn the Front end — Geek Time APP
  • Object to primitive conversion
  • ToPrimitive



If you think this article is good, share it with your friends