简体   繁体   中英

Coercion in JavaScript - Abstract Methods

I have recently started learning more about coercion in Js and I have been going through the ECMAScript documentation for knowing more about it and how different cases are handled in Js. While doing I encountered the following statement

10-{"a":10,valueOf(){return 8;}}
>2

This is the problem along with the output from my browser console can you help me decode how the result comes step by step I did try the simpler version of the same problem which included only the {"a":10} part and thus

10-{"a":10}
>NaN

understood how the Nan result is obtained but didn't get the first stated problem where the result is 2 Also, one more thing the function valueOf() will return 8 but that will be inside the object's braces isn't it like {"a":10,8}, or is something else happening? So help me understand why Is result 2?

10-{"a":10,valueOf(){return 8;}} is doing 10 minus an object, where the object has a property called a with the value 10 (which is irrelevant; it's not used), and a valueOf method that returns 8 (which is very relevant:-) ).

The subtraction operator requires that its operands be numbers. When one of its operands isn't a number, it uses the abstract ToNumber operation on it to convert it to number. For an object (as in your example), ToNumber uses ToPrimitive saying its preferred type is "number". In the case of an ordinary object (such as yours), that ends up doing OrdinaryToPrimitive . OrdinaryToPrimitive looks to see if the object has certain methods that can be used to get a primitive from the object. When the preferred type is "number," the first method OrdinaryToPrimitive tries is valueOf . So that method of your object is called, returns 8 , and 10-8 is performed (resulting in 2 ).

Here's that code written more clearly, and without any implicit type conversion:

 const obj = { // Left `a` off because it's never used for anything valueOf() { return 8; } }; const numberForObj = obj.valueOf(); console.log(`numberForObj = ${numberForObj}`); const result = 10 - numberForObj; console.log(`result = ${result}`);

The a:10 part is insignificant and can be omitted.

When coercing to numbers, objects that provide valueOf can use the return value of this function:

 var p = { valueOf() { return 8; } } console.log( +p )

Thus, the expression can be simplified to

 console.log( 10-{valueOf(){return 8;}} )

The first step to understanding what's going on is to understand what valueOf does. You can think of it similar to toString . toString is used when an object needs to be turned into string form:

 const identity = { firstName: "Martha", lastName: "Stewart", toString() { return this.firstName + " " + this.lastName; } }; console.log("Name: " + identity);

valueOf is similar, except it's used when an object needs to be turned into a number:

 const budget = { bank: 3, wallet: 5, valueOf() { return this.bank + this.wallet; } }; console.log(10 + budget);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM