简体   繁体   English

JavaScript 中的强制 - 抽象方法

[英]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.我最近开始学习更多关于 Js 中的强制转换的知识,并且我一直在阅读 ECMAScript 文档以了解更多关于它以及 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这是我的浏览器控制台中的 output 的问题,你能帮我解码结果是如何一步一步地得出的吗?我确实尝试了相同问题的更简单版本,其中仅包含 {"a":10} 部分

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?了解如何获得 Nan 结果,但没有得到结果为 2 的第一个问题 此外,还有一件事 function valueOf() 将返回 8 但这将在对象的大括号内是不是就像 {"a ":10,8},还是发生了其他事情? So help me understand why Is result 2?所以帮助我理解为什么是结果 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:-) ). 10-{"a":10,valueOf(){return 8;}}10减去 object,其中 object 有一个名为a的属性,其值为10 (无关紧要;未使用)和valueOf返回8的方法(非常相关:-))。

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.当它的操作数之一不是数字时,它使用抽象的ToNumber操作将其转换为数字。 For an object (as in your example), ToNumber uses ToPrimitive saying its preferred type is "number".对于 object (如您的示例), ToNumber 使用ToPrimitive表示其首选类型是“数字”。 In the case of an ordinary object (such as yours), that ends up doing OrdinaryToPrimitive .对于普通的 object (例如您的),最终会执行OrdinaryToPrimitive OrdinaryToPrimitive looks to see if the object has certain methods that can be used to get a primitive from the object. OrdinaryToPrimitive 查看 object 是否有某些方法可用于从 object 获取原语。 When the preferred type is "number," the first method OrdinaryToPrimitive tries is valueOf .当首选类型是“数字”时,OrdinaryToPrimitive 尝试的第一个方法是valueOf So that method of your object is called, returns 8 , and 10-8 is performed (resulting in 2 ).因此调用 object 的方法,返回8 ,并执行10-8 (导致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. a:10部分无关紧要,可以省略。

When coercing to numbers, objects that provide valueOf can use the return value of this function:强制转换为数字时,提供valueOf的对象可以使用此 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.了解发生了什么的第一步是了解valueOf做了什么。 You can think of it similar to toString .你可以把它想象成类似于toString toString is used when an object needs to be turned into string form:当需要将 object 转换为字符串形式时使用toString

 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: valueOf是类似的,除了它在 object 需要转换为数字时使用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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