이 기사는 ECMAScript7 사양의 ToPrimitive 추상 연산에 대한 자세한 분석(예제)을 제공합니다. 필요한 친구가 참고할 수 있기를 바랍니다.
이 기사에서는 ECMAScript7 사양의 ToPrimitive 추상 작업을 소개합니다.
ECMAScript 데이터 유형은 두 가지 주요 데이터 유형 범주로 나누어집니다. 하나는 언어 유형이고 다른 하나는 사양 유형입니다.
언어 유형은 개발자가 직접 사용할 수 있는 데이터 유형입니다.
표준 유형은 ECMAScript 언어 구조 및 언어 유형의 의미를 설명하기 위해 알고리즘에 사용되는 메타 값(메타 값)을 나타냅니다. 주로 사양 설명에 사용되며 실제로 구현할 필요는 없습니다.
ECMAScript에는 총 7가지 언어 유형이 있습니다.
Undefine
Null
Boolean, Boolean 유형
String, 문자열 유형
Symbol, 기호 유형
Number, 숫자 유형
Object, 객체 유형
원시 데이터형은 위에서 언급한 비객체 데이터형인 Undefine, Null, Boolean, String, Symbol, Number를 총칭하는 명칭이다.
아래에 언급된 유일한 표준 유형은 List입니다. 이는 배열과 유사한 목록이며 « » 기호로 표시됩니다.
Symbol에는 Symbol 객체에 정의된 속성인 Symbol.toPrimitive인 @@toPrimitive와 같은 유명한 기호가 많이 있습니다.
이 추상 연산은 매개변수 입력과 선택적 매개변수 PreferredType을 허용합니다. 이 추상 연산의 목적은 매개변수 입력을 비객체 데이터 유형, 즉 원시 데이터 유형으로 변환하는 것입니다. 입력을 동시에 여러 원시 데이터로 변환할 수 있는 경우 PreferredType 값이 먼저 참조됩니다. 변환 과정은 아래 표를 참조하세요.
매개변수의 데이터 유형input
|
result |
---|---|
Undefine | 입력 자체 반환 |
Null | 입력 자체 반환 |
부울 | 입력 자체 반환 |
Number | 입력 자체 반환 |
String | 입력 자체 반환 |
Symbol | 입력 자체 반환 |
객체 | 다음 단계를 실행하세요 |
입력 데이터 유형이 객체인 경우 다음 단계를 수행합니다.
1. PreferredType 매개변수가 전달되지 않은 경우 힌트를 "default"로 설정합니다.
2. PreferredType이 힌트 문자열로 설정합니다. "string";
3. PreferredType이 힌트 숫자인 경우 힌트를 "숫자"와 동일하게 둡니다.
4.exoticToPrim을 GetMethod(input, @@toPrimitive)와 같게 하면 아마도 @@를 얻는 것입니다.
5.exoticToPrim이 정의되지 않은 경우:
결과를 Call(exoticToPrim, input, « 힌트 »)와 동일하게 합니다.
If를 실행합니다. 결과는 기본 데이터 유형입니다.
잘못된 유형으로 예외를 발생시킵니다.
6. 힌트가 "숫자"인 경우
7. 힌트) 추상 작업.
O의 데이터 유형은 객체이고, 힌트의 데이터 유형은 문자열이며, 힌트의 값은 "문자열" 또는 "숫자"입니다. 이 추상 작업의 단계는 다음과 같습니다.
1. 힌트가 "string"인 경우 methodNames가 "toString", "valueOf""인 경우
2. 힌트가 "number"인 경우 methodNames가 ""인 경우 valueOf", "toString" »;
3. 각 반복 값 이름에 대해 methodNames 목록을 순서대로 반복합니다.
메서드를 Call(method, O)와 같게 하면 대략적인 의미는 method()를 실행하는 것입니다.
If 결과 유형이 객체가 아닌 경우 결과를 반환합니다.
메서드를 Get(O, name)으로 설정하면 대략적인 의미는 객체 O의 이름 값에 해당하는 속성을 가져오는 것입니다. 그런 다음:
4. 잘못된 유형의 예외를 발생시킵니다.
위 단계에서 알 수 있습니다.
ToPrimitive의 6단계에서 선택적 매개변수 PreferredType이 제공되지 않으면 힌트가 기본값으로 "숫자"로 설정된다는 것을 알 수 있습니다.
ToPrimitive의 4단계에서 알 수 있습니다. @@toPrimitive 메서드를 정의하여 기본 동작을 재정의할 수 있는 ToPrimitive 예를 들어 사양에 정의된 Date 개체 및 Symbol 개체에는 프로토타입에 정의된 @@toPrimitive 메서드가 있습니다.
Practice
'' + [1, 2, 3]
'' + [1, 2, 3] // "1,2,3"
var a = [1, 2, 3] a.valueOf() // [1, 2, 3],数组a本身 a.toString() // "1,2,3"
valueOf는 배열 자체 또는 객체 유형을 반환하므로 계속해서 toString 메서드를 호출하고 "1,2,3" 문자열을 반환하므로
'' + [1, 2, 3] // => '' + '1,2,3' => '1,2,3'
그런 다음 배열의 valueOf 메서드를 재정의하면 프로토타입을 사용하여 메소드가 기본 데이터 유형을 반환하게 하면 결과는 어떻게 될까요?
var a = [1, 2, 3] a.valueOf = function () { console.log('trigger valueOf') return 'hello' } '' + a // => '' + 'hello' => 'hello'
기본 valueOf를 재정의한 후 valueOf를 호출하면 원래 데이터 유형이 반환됩니다. OrdinaryToPrimitive의 3.2.2에 따르면 이때 직접 반환하고 toString 메서드는 다시 호출되지 않습니다. 동시에 "trigger valueOf"가 콘솔에 기록됩니다. 이는 valueOf가 실제로 호출되었음을 의미합니다.
그럼 배열의 기본 toString 메서드를 재정의하여 메서드가 객체 유형을 반환하도록 하면 결과는 어떻게 될까요?var a = [1, 2, 3] a.toString = function () { console.log('trigger toString') return this } '' + a // Uncaught TypeError: Cannot convert object to primitive value
var a = [1, 2, 3] a[Symbol.toPrimitive] = function () { return 'custom' } '' + a // => '' + 'custom' => 'custom'
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"}
변수를 키 값으로 사용하는 경우 ToPrimitive가 호출되어 키 값을 기본 데이터 유형으로 변환하며 PreferredType의 값은 힌트 문자열입니다. 위의 예에서도 a.valueOf와 a.toString의 결과는 모두 문자열이지만 a.toString을 사용한 결과인 '1,2,3'이 사용된 것을 알 수 있습니다. 물론 toString 메소드를 재정의하고 객체를 반환하면 valueOf의 값이 사용됩니다.
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"}
및 "trigger toString"이 콘솔에 먼저 기록된 다음 "trigger valueOf"가 기록됩니다. 물론, 이 두 객체가 모두 반환되면 오류가 계속 보고됩니다:
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抽象操作,以及一些相关的例子,希望大家能有所收获。
위 내용은 ECMAScript7 사양의 ToPrimitive 추상 연산 지식에 대한 자세한 설명(예)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!