Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung des Wissens über die abstrakte ToPrimitive-Operation in der ECMAScript7-Spezifikation (Beispiel)

Detaillierte Erläuterung des Wissens über die abstrakte ToPrimitive-Operation in der ECMAScript7-Spezifikation (Beispiel)

不言
不言Original
2018-09-17 14:53:074632Durchsuche

Dieser Artikel bietet Ihnen eine detaillierte Analyse (Beispiel) der ToPrimitive-Abstraktoperation in der ECMAScript7-Spezifikation. Ich hoffe, dass er für Sie hilfreich ist.

In diesem Artikel wird die abstrakte ToPrimitive-Operation in der ECMAScript7-Spezifikation vorgestellt.

Vorkenntnisse

ECMAScript-Datentypen

ECMAScript-Datentypen sind in zwei Hauptkategorien von Datentypen unterteilt, eine ist der Sprachtyp und die andere ist der Spezifikationstyp:

Sprachtypen sind Datentypen, die direkt von Entwicklern verwendet werden können

Kanonische Typen stellen Metawerte (Metawerte) dar, die in Algorithmen zur Beschreibung der Semantik der ECMAScript-Sprache verwendet werden Strukturen und Sprachtypen. Sie werden hauptsächlich zur Spezifikationsbeschreibung verwendet und müssen nicht tatsächlich implementiert werden.

ECMAScript hat insgesamt 7 Sprachtypen:

Undefiniert

Null

Boolean, Boolean-Typ

String, String-Typ

Symbol, Symboltyp

Zahl, Zahlentyp

Objekt, Objekttyp

Die ursprünglichen Datentypen sind die oben genannten Undefiniert, Null, Boolean, String, Symbol und Zahl, bei denen es sich um Nicht-Objekt-Datentypen handelt.
Der einzige unten erwähnte Standardtyp ist Liste, eine Liste, ähnlich einem Array, die durch das Symbol „“ dargestellt wird.

@@toPrimitive

Symbol hat viele berühmte Symbole, wie z. B. @@toPrimitive, das Symbol.toPrimitive ist, ein Attribut, das für das Symbolobjekt definiert ist.

ToPrimitive(input [, PreferredType])

Diese abstrakte Operation akzeptiert eine Parametereingabe und einen optionalen Parameter PreferredType. Der Zweck dieser abstrakten Operation besteht darin, die Parametereingabe in einen Nicht-Objekt-Datentyp, dh einen primitiven Datentyp, umzuwandeln. Wenn die Eingabe gleichzeitig in mehrere Rohdaten konvertiert werden kann, wird zuerst auf den Wert von PreferredType verwiesen. Den Konvertierungsprozess entnehmen Sie bitte der folgenden Tabelle:

参数input的数据类型 结果
Undefined 返回input自身
Null 返回input自身
Boolean 返回input自身
Number 返回input自身
String 返回input自身
Symbol 返回input自身
Object 执行下面的步骤

Wenn der Eingabedatentyp ein Objekt ist, führen Sie die folgenden Schritte aus:

1. Wenn der PreferredType-Parameter nicht übergeben wird, lassen Sie den Hinweis gleich „default“; Wenn PreferredType gleich „string“ ist, sei hint gleich „number“; sei „exoticToPrim“ gleich to GetMethod(input, @@toPrimitive), Die ungefähre Semantik ist die @@toPrimitive-Methode zum Erhalten der Parametereingabe; to Call(exoticToPrim, input, „hint“) Die ungefähre Semantik ist Execute exoticToPrim(hint);

Wenn das Ergebnis ein primitiver Datentyp ist, wird das Ergebnis zurückgegeben Fehler;

6. Wenn der Hinweis „Standard“ ist, geben Sie das Ergebnis der abstrakten Operation „OrdinaryToPrimitive“ zurück.

OrdinaryToPrimitive(O, hint)

Der Datentyp von O ist Objekt, der Datentyp von Hint ist String und der Wert von Hint ist entweder „String“ oder „Zahl“. Die Schritte dieser abstrakten Operation sind wie folgt:

1. Wenn der Hinweis „string“ ist, seien methodNames gleich „toString“, „valueOf“ »; number“, Lassen Sie methodNames gleich „valueOf“, „toString“ »;

3. Iterieren Sie die Liste der Methodennamen der Reihe nach für jeden Iterationswertnamen:

Let method equal Call(method , O), Die ungefähre Semantik besteht darin, method();

Wenn der Ergebnistyp kein Objekt ist, das Ergebnis zurückzugeben Die ungefähre Semantik besteht darin, den Namenswert zu erhalten, der den Objekt-O-Attributen entspricht.

Wenn die Methode aufgerufen werden kann, dann:

4.

Aus den obigen Schritten geht hervor:

Aus Schritt 6 von ToPrimitive geht hervor, dass der Hinweis standardmäßig auf „Nummer“ gesetzt ist, wenn der optionale Parameter „PreferredType“ nicht angegeben ist >

Passed Step 4 von ToPrimitive zeigt, dass Sie das Standardverhalten überschreiben können, indem Sie die @@toPrimitive-Methode definieren. Beispielsweise ist für das in der Spezifikation definierte Date-Objekt und das Symbol-Objekt beide die @@toPrimitive-Methode im Prototyp definiert.

Übung

Einige Leute fragen sich vielleicht, warum wir die abstrakten Methoden in der Spezifikation erklären müssen. Ich verwende keine abstrakten Methoden. Tatsächlich wird diese Methode vielerorts verwendet, aber man weiß es einfach nicht. Lassen Sie uns unser Verständnis vertiefen, indem wir im Folgenden einige Beispiele erläutern.

'' + [1, 2, 3]

'' + [1, 2, 3] // "1,2,3"
Gemäß der Additionsoperation in der Spezifikation gelten für die Operation x + y ToPrimitive(x) und ToPrimitive(y). aufgerufen, um x y zu summieren, wird in einen primitiven Datentyp konvertiert. Im obigen Beispiel ist '' selbst ein primitiver Datentyp, daher wird '' selbst zurückgegeben. [1, 2, 3] ist ein Objekttyp und das Array definiert nicht die @@toPrimitive-Eigenschaft. Da der PreferredType nicht bereitgestellt wird, wird der Hinweis in Schritt 6 der ToPrimitive-Operation zu „number“, sodass die Methodennamen in OrdinaryToPrimitive „„valueOf“, „toString““ sind.

var a = [1, 2, 3]
a.valueOf() // [1, 2, 3],数组a本身
a.toString() // "1,2,3"
Da valueOf das Array a selbst oder den Objekttyp zurückgibt, ruft es weiterhin die toString-Methode auf und gibt die Zeichenfolge „1,2,3“ zurück, also

'' + [1, 2, 3] // => '' + '1,2,3' => '1,2,3'
Dann, wenn Wir überschreiben die valueOf-Methode im Array-Prototyp, sodass die Methode einen primitiven Datentyp zurückgibt. Was wird also das Ergebnis sein?

var a = [1, 2, 3]
a.valueOf = function () {
    console.log('trigger valueOf')
    return 'hello'
}
'' + a //  => '' + 'hello' => 'hello'
Nach dem Überschreiben des Standardwerts von valueOf wird beim Aufruf von valueOf der ursprüngliche Datentyp zurückgegeben. Gemäß 3.2.2 von OrdinaryToPrimitive wird zu diesem Zeitpunkt direkt zurückgegeben und die toString-Methode wird nicht erneut aufgerufen. Gleichzeitig wird „trigger valueOf“ auf der Konsole protokolliert, was bedeutet, dass valueOf tatsächlich aufgerufen wird.

Was wird also das Ergebnis sein, wenn wir die standardmäßige toString-Methode des Arrays überschreiben, sodass die Methode den Objekttyp zurückgibt?

var a = [1, 2, 3]
a.toString = function () {
    console.log('trigger toString')
    return this
}
'' + a // Uncaught TypeError: Cannot convert object to primitive value

Da die valueOf-Methode im Array-Prototyp den Objekttyp zurückgibt, überschreiben wir im obigen Beispiel toString, sodass auch der Objekttyp zurückgegeben wird. Dann gehen wir direkt zu Schritt 4 von OrdinaryToPrimitive Dies bedeutet, dass eine Ausnahme vom Typ Fehler ausgelöst wird und das Objekt nicht in den ursprünglichen Datentyp konvertiert werden kann.

Wir haben oben erwähnt, dass Sie das Verhalten von ToPrimitive über die @@toPrimitive-Methode anpassen können, wie im folgenden Beispiel:

var a = [1, 2, 3]
a[Symbol.toPrimitive] = function () {
    return 'custom'
}
'' + a // => '' + 'custom' => 'custom'
Die Additionsoperation stellt beim Aufruf von ToPrimitive keinen PreferredType bereit. Lassen Sie uns als Nächstes sprechen Darüber Ein Beispiel für die bevorzugte Verwendung eines Hint-Strings als 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"}

Wenn eine Variable als Schlüsselwert verwendet wird, wird ToPrimitive aufgerufen, um den Schlüsselwert in den ursprünglichen Datentyp zu konvertieren, und der Wert von PreferredType ist hint Zeichenfolge. Aus dem obigen Beispiel ist auch ersichtlich, dass die Ergebnisse von a.valueOf und a.toString beide Zeichenfolgen sind, aber „1,2,3“ verwendet wird, was das Ergebnis der Verwendung von a.toString ist. Wenn wir die toString-Methode neu definieren und das Objekt zurückgeben, wird natürlich der Wert von valueOf verwendet:

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"}
und „trigger toString“ wird zuerst auf der Konsole protokolliert und dann „trigger valueOf“. protokolliert werden. Wenn beide Objekte zurückgegeben werden, wird natürlich trotzdem ein Fehler gemeldet:

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

Datum

在上面讲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抽象操作,以及一些相关的例子,希望大家能有所收获。

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Wissens über die abstrakte ToPrimitive-Operation in der ECMAScript7-Spezifikation (Beispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn