


Detailed explanation of the knowledge of ToPrimitive abstract operation in ECMAScript7 specification (example)
This article brings you a detailed analysis (example) of the ToPrimitive abstract operation in the ECMAScript7 specification. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
This article will introduce the ToPrimitive abstract operation in the ECMAScript7 specification.
Preliminary knowledge
ECMAScript data types
ECMAScript data types are subdivided into two major categories of data types, one is the language type and the other is the specification type:
Language types are data types that can be used directly by developers;
Canonical types represent meta-values (meta-values), which are used in algorithms to describe the semantics of ECMAScript language structures and language types. They are mainly used for specification description and do not need to be actually implemented.
There are 7 language types in ECMAScript:
Undefined
Null
Boolean, Boolean type
String, string type
Symbol, symbol type
Number, number type
Object, object type
The original data types are the above Undefined, Null, Boolean, String, Symbol and Number, which are non-object data types.
The standard type mentioned below is only List, which is a list, similar to an array, represented by the symbol « ».
@@toPrimitive
Symbol has many famous symbols, such as @@toPrimitive, which is Symbol.toPrimitive, which is an attribute defined on the Symbol object.
ToPrimitive(input [, PreferredType])
This abstract operation accepts a parameter input and an optional parameter PreferredType. The purpose of this abstract operation is to convert the parameter input into a non-object data type, that is, a primitive data type. If the input can be converted into multiple raw data at the same time, the value of PreferredType will be referenced first. Refer to the following table for the conversion process:
Data type of parameter input
|
Result |
---|---|
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 |
If the input data type is an object, perform the following steps:
1. If the PreferredType parameter is not passed in, let hint equal "default";
2. If PreferredType is hint String, let hint be equal to "string";
3. If PreferredType is hint Number, let hint be equal to "number";
4. Let exoticToPrim be equal to GetMethod(input, @@toPrimitive), The approximate semantics is the @@toPrimitive method to obtain the parameter input;
5. If exoticToPrim is not Undefined, then:
Let result equal to Call(exoticToPrim, input, « hint »), the approximate semantics is Execute exoticToPrim(hint);
If result is a primitive data type, return result;
Throw an exception of type error;
6. If hint is "default", Let hint equal "number";
7. Return the result of the OrdinaryToPrimitive(input, hint) abstract operation.
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. If hint is "string", let methodNames equal « "toString", "valueOf" »;
2. If hint is "number", Let methodNames equal « "valueOf", "toString" »;
3. Iterate the list of methodNames in order, for each iteration value name:
Let method equal Call(method, O), The approximate semantics is to execute method();
If the type of result is not an object, return result;
Let method equal Get(O, name), the approximate semantics is to obtain the name value corresponding to object O Attributes;
If the method can be called, then:
4. Throw an exception of the wrong type.
It can be seen from the above steps:
It can be seen from step 6 of ToPrimitive that when the optional parameter PreferredType is not provided, hint will default to "number";
Passed Step 4 of ToPrimitive shows that you can override the default behavior by defining the @@toPrimitive method. For example, the Date object and Symbol object defined in the specification both have the @@toPrimitive method defined on the prototype.
Practice
Some people may ask why we need to explain the abstract methods in the specification. I don’t use abstract methods. In fact, this method is used in many places, but you just don’t know it. Below, we will explain a few examples to help you deepen your understanding of it.
'' [1, 2, 3]
'' + [1, 2, 3] // "1,2,3"
According to the addition operation in the specification, for the operation x y, ToPrimitive(x) and ToPrimitive(y) will be called to convert x and y into Primitive data type. In the above example, '' itself is a primitive data type, so '' itself is returned. [1, 2, 3] is an object type, and the array does not define the @@toPrimitive property. Because the PreferredType is not provided, in step 6 of the ToPrimitive operation, the hint becomes "number", so the methodNames in OrdinaryToPrimitive are « "valueOf", "toString" ».
var a = [1, 2, 3] a.valueOf() // [1, 2, 3],数组a本身 a.toString() // "1,2,3"
Because valueOf returns the array a itself or the object type, it will continue to call the toString method and return the string "1,2,3", so
'' + [1, 2, 3] // => '' + '1,2,3' => '1,2,3'
Then, if We override the valueOf method on the array prototype so that the method returns a primitive data type. So what will the result be?
var a = [1, 2, 3] a.valueOf = function () { console.log('trigger valueOf') return 'hello' } '' + a // => '' + 'hello' => 'hello'
After overriding the default valueOf, calling valueOf will return the original data type. According to 3.2.2 of OrdinaryToPrimitive, it returns directly at this time and the toString method will not be called again. At the same time, "trigger valueOf" will be logged on the console, which means that valueOf is indeed called.
So, if we override the default toString method of the array so that the method returns the object type, what will be the result?
var a = [1, 2, 3] a.toString = function () { console.log('trigger toString') return this } '' + a // Uncaught TypeError: Cannot convert object to primitive value
Because the valueOf method on the array prototype returns the object type, in the above example, we overwrite toString so that it also returns the object type, then we will go directly to step 4 of OrdinaryToPrimitive, that is It just throws a type error exception and cannot convert the object into the original data type.
We mentioned above that you can customize the behavior of ToPrimitive through the @@toPrimitive method, such as the following example:
var a = [1, 2, 3] a[Symbol.toPrimitive] = function () { return 'custom' } '' + a // => '' + 'custom' => 'custom'
The addition operation does not provide a PreferredType when calling ToPrimitive. Let’s talk about it next. Example of preferentially using hint String as PreferredType:
var a = [1, 2, 3] a.valueOf = function () { console.log('trigger valueOf') return 'hello' } a.valueOf() // "hello" a.toString() // "1,2,3" var obj = {} obj[a] = 'hello' // obj是{1,2,3: "hello"}
When using a variable as a key value, ToPrimitive will be called to convert the key value into the original data type, and the value of PreferredType is hint String. It can also be seen from the above example that the results of a.valueOf and a.toString are both strings, but '1,2,3' is used, which is the result of using a.toString. Of course, if we redefine the toString method and return the object, then the value of valueOf will be used:
var a = [1, 2, 3] a.valueOf = function () { console.log('trigger valueOf') return 'hello' } a.toString = function () { console.log('trigger toString') return this } var obj = {} obj[a] = 'hello' // obj是{hello: "hello"}
and "trigger toString" will be logged on the console first, and then "trigger valueOf" will be logged. Of course, if both of these return objects, an error will still be reported:
var a = [1, 2, 3] // 使用原型链上的valueOf方法 a.toString = function () { console.log('trigger toString') return this } var obj = {} obj[a] = 'hello' // Uncaught TypeError: Cannot convert object to primitive value
Date
在上面讲ToPrimitive的时候,提到Date对象和Symbol对象在原型上定义了@@toPrimitive方法。在ToPrimitive的第6步的操作中,我们可以看到当没有提供PreferredType的时候,优先调用valueOf方法。Date原型上的@@toPrimitive做的事情非常简单:当没有提供PreferredType的时候,优先调用toString方法。所以对于上面的操作,Date对象的行为是不一样的:
var a = [1, 2, 3] a.valueOf = function () { return 'hello' } a.valueOf() // "hello" a.toString() // "1,2,3" '' + a // "hello" var date = new Date() date.valueOf() // 1536416960724 date.toString() // "Sat Sep 08 2018 22:29:20 GMT+0800 (中国标准时间)" '' + date // "Sat Sep 08 2018 22:29:20 GMT+0800 (中国标准时间)"
我们可以看到date的valueOf方法和toString方法都返回原始数据类型,但是优先使用了toString方法。
总结
本文主要讲解了ToPrimitive抽象操作,以及一些相关的例子,希望大家能有所收获。
The above is the detailed content of Detailed explanation of the knowledge of ToPrimitive abstract operation in ECMAScript7 specification (example). For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

How to use WebSocket and JavaScript to implement an online speech recognition system Introduction: With the continuous development of technology, speech recognition technology has become an important part of the field of artificial intelligence. The online speech recognition system based on WebSocket and JavaScript has the characteristics of low latency, real-time and cross-platform, and has become a widely used solution. This article will introduce how to use WebSocket and JavaScript to implement an online speech recognition system.

WebSocket and JavaScript: Key technologies for realizing real-time monitoring systems Introduction: With the rapid development of Internet technology, real-time monitoring systems have been widely used in various fields. One of the key technologies to achieve real-time monitoring is the combination of WebSocket and JavaScript. This article will introduce the application of WebSocket and JavaScript in real-time monitoring systems, give code examples, and explain their implementation principles in detail. 1. WebSocket technology

Introduction to how to use JavaScript and WebSocket to implement a real-time online ordering system: With the popularity of the Internet and the advancement of technology, more and more restaurants have begun to provide online ordering services. In order to implement a real-time online ordering system, we can use JavaScript and WebSocket technology. WebSocket is a full-duplex communication protocol based on the TCP protocol, which can realize real-time two-way communication between the client and the server. In the real-time online ordering system, when the user selects dishes and places an order

How to use WebSocket and JavaScript to implement an online reservation system. In today's digital era, more and more businesses and services need to provide online reservation functions. It is crucial to implement an efficient and real-time online reservation system. This article will introduce how to use WebSocket and JavaScript to implement an online reservation system, and provide specific code examples. 1. What is WebSocket? WebSocket is a full-duplex method on a single TCP connection.

JavaScript and WebSocket: Building an efficient real-time weather forecast system Introduction: Today, the accuracy of weather forecasts is of great significance to daily life and decision-making. As technology develops, we can provide more accurate and reliable weather forecasts by obtaining weather data in real time. In this article, we will learn how to use JavaScript and WebSocket technology to build an efficient real-time weather forecast system. This article will demonstrate the implementation process through specific code examples. We

JavaScript tutorial: How to get HTTP status code, specific code examples are required. Preface: In web development, data interaction with the server is often involved. When communicating with the server, we often need to obtain the returned HTTP status code to determine whether the operation is successful, and perform corresponding processing based on different status codes. This article will teach you how to use JavaScript to obtain HTTP status codes and provide some practical code examples. Using XMLHttpRequest

Usage: In JavaScript, the insertBefore() method is used to insert a new node in the DOM tree. This method requires two parameters: the new node to be inserted and the reference node (that is, the node where the new node will be inserted).

JavaScript is a programming language widely used in web development, while WebSocket is a network protocol used for real-time communication. Combining the powerful functions of the two, we can create an efficient real-time image processing system. This article will introduce how to implement this system using JavaScript and WebSocket, and provide specific code examples. First, we need to clarify the requirements and goals of the real-time image processing system. Suppose we have a camera device that can collect real-time image data
