Maison  >  Article  >  interface Web  >  Explication détaillée de la connaissance de l'opération abstraite ToPrimitive dans la spécification ECMAScript7 (exemple)

Explication détaillée de la connaissance de l'opération abstraite ToPrimitive dans la spécification ECMAScript7 (exemple)

不言
不言original
2018-09-17 14:53:074625parcourir

Ce que cet article vous apporte est une analyse détaillée (exemple) de l'opération abstraite ToPrimitive dans la spécification ECMAScript7. Elle a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Cet article présentera l'opération abstraite ToPrimitive dans la spécification ECMAScript7.

Connaissances préliminaires

Types de données ECMAScript

Les types de données ECMAScript sont subdivisés en deux grandes catégories de types de données, l'une est le type de langage et l'autre est le type de spécification :

Les types de langage sont des types de données qui peuvent être utilisés directement par les développeurs

Les types canoniques représentent des méta-valeurs (méta-valeurs), qui sont utilisées dans les algorithmes pour décrire la sémantique du langage ECMAScript. structures et types de langage. Ils sont principalement utilisés pour la description des spécifications et n’ont pas besoin d’être réellement implémentés.

ECMAScript a un total de 7 types de langage :

Non défini

Null

Booléen, type booléen

Chaîne, type de chaîne

Symbole, type de symbole

Nombre, type de nombre

Objet, type d'objet

Les types de données d'origine sont les suivants : Indéfini, Null, Booléen, Chaîne, Symbole et Nombre, qui sont des types de données non-objet.
Le seul type standard mentionné ci-dessous est List, qui est une liste, semblable à un tableau, représentée par le symbole « ».

@@toPrimitive

Symbol a de nombreux symboles célèbres, tels que @@toPrimitive, qui est Symbol.toPrimitive, qui est un attribut défini sur l'objet Symbol.

ToPrimitive(input [, PreferredType])

Cette opération abstraite accepte un paramètre d'entrée et un paramètre facultatif PreferredType. Le but de cette opération abstraite est de convertir le paramètre entré en un type de données non-objet, c'est-à-dire un type de données primitif. Si l'entrée peut être convertie en plusieurs données brutes en même temps, la valeur de PreferredType sera référencée en premier. Veuillez vous référer au tableau ci-dessous pour le processus de conversion :

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

Si le type de données d'entrée est un objet, effectuez les étapes suivantes :

1. Si le paramètre PreferredType n'est pas transmis, laissez l'indice égal à "par défaut" ; Si PreferredType est une chaîne d'indice, laissez l'indice être égal à "string"

3. Si PreferredType est un numéro d'indice, laissez l'indice être égal à "numéro" ; to GetMethod(input, @@toPrimitive), La sémantique approximative est la méthode @@toPrimitive d'obtention du paramètre d'entrée

5 Si exotiqueToPrim n'est pas indéfini, alors :

Laissez le résultat égal ; to Call(exoticToPrim, input, « highlight »). La sémantique approximative est Execute exotiqueToPrim(hint);

Si le résultat est un type de données primitif, renvoie le résultat

Lance une exception de type ; error;

6. Si l'indice est "par défaut", laissez l'indice égal à "numéro"

7. Renvoie le résultat de l'opération abstraite OrdinaryToPrimitive (input, suggest).

OrdinaryToPrimitive(O, soupçon)

Le type de données de O est un objet, le type de données de l'indice est une chaîne et la valeur de l'indice est soit "chaîne" soit "nombre". Les étapes de cette opération abstraite sont les suivantes :

1. Si l'indice est "string", laissez methodNames égal à « "toString", "valueOf" » ;

2. number", Laissez methodNames égal à « "valueOf", "toString" »;

3. Itérez la liste des methodNames dans l'ordre, pour chaque nom de valeur d'itération :

Laissez la méthode égale Call(method , O), La sémantique approximative est d'exécuter method();

Si le type de résultat n'est pas un objet, renvoie le résultat

Laissez la méthode égale Get(O, name), le la sémantique approximative consiste à obtenir la valeur du nom correspondant à l'objet O Attributs ;

Si la méthode peut être appelée, alors :

4.

On peut le voir à partir des étapes ci-dessus :

On peut voir à l'étape 6 de ToPrimitive que lorsque le paramètre facultatif PreferredType n'est pas fourni, l'indice sera par défaut "number"

L'étape 4 réussie de ToPrimitive montre que vous pouvez remplacer le comportement par défaut en définissant la méthode @@toPrimitive. Par exemple, l'objet Date et l'objet Symbol définis dans la spécification ont tous deux la méthode @@toPrimitive définie sur le prototype.

Pratique

Certaines personnes peuvent se demander pourquoi nous devons expliquer les méthodes abstraites dans la spécification. Je n'utilise pas de méthodes abstraites. En fait, cette méthode est utilisée dans de nombreux endroits, mais vous ne la connaissez tout simplement pas. Ci-dessous, nous expliquerons quelques exemples pour vous aider à approfondir votre compréhension.

'' + [1, 2, 3]

Selon l'opération d'addition dans la spécification, pour l'opération x + y, ToPrimitive(x) et ToPrimitive(y) seront appelés x et y sont convertis en types de données primitifs. Dans l'exemple ci-dessus, '' lui-même est un type de données primitif, donc '' lui-même est renvoyé. [1, 2, 3] est un type d'objet et le tableau ne définit pas la propriété @@toPrimitive. Parce que le PreferredType n'est pas fourni, à l'étape 6 de l'opération ToPrimitive, l'indice devient "number", donc les methodNames dans OrdinaryToPrimitive sont « "valueOf", "toString" ».

Parce que valueOf renvoie le tableau a lui-même ou le type d'objet, il continuera à appeler la méthode toString et retournera la chaîne "1,2,3", donc
'' + [1, 2, 3] // "1,2,3"

Donc, si nous remplaçons la méthode valueOf sur le prototype de tableau afin que la méthode renvoie un type de données primitif, quel sera le résultat ?
var a = [1, 2, 3]
a.valueOf() // [1, 2, 3],数组a本身
a.toString() // "1,2,3"

Après avoir remplacé la valeur par défaut valueOf, l'appel de valueOf renverra le type de données d'origine. Selon 3.2.2 d'OrdinaryToPrimitive, il revient directement à ce moment et la méthode toString ne sera plus appelée. En même temps, "trigger valueOf" sera enregistré sur la console, ce qui signifie que valueOf est bien appelé.
'' + [1, 2, 3] // => '' + '1,2,3' => '1,2,3'
Donc, si nous remplaçons la méthode toString par défaut du tableau pour que la méthode renvoie le type d'objet, quel sera le résultat ?

var a = [1, 2, 3]
a.valueOf = function () {
    console.log('trigger valueOf')
    return 'hello'
}
'' + a //  => '' + 'hello' => 'hello'
Parce que la méthode valueOf sur le prototype de tableau renvoie le type d'objet, dans l'exemple ci-dessus, nous remplaçons toString pour qu'il renvoie également le type d'objet, puis nous passerons directement à l'étape 4 de OrdinaryToPrimitive , c'est-à-dire qu'une exception d'erreur de type est levée et l'objet ne peut pas être converti en un type de données primitif.

Nous avons mentionné ci-dessus que le comportement de ToPrimitive peut être personnalisé via la méthode @@toPrimitive, comme dans l'exemple suivant :

var a = [1, 2, 3]
a.toString = function () {
    console.log('trigger toString')
    return this
}
'' + a // Uncaught TypeError: Cannot convert object to primitive value
L'opération d'ajout ne fournit pas de PreferredType lors de l'appel de ToPrimitive. suivant Un exemple d'utilisation préférentielle de la chaîne d'indice comme PreferredType :


Lors de l'utilisation de variables comme valeurs clés, ToPrimitive sera appelé pour convertir la valeur clé dans le type de données d'origine, et la valeur de PreferredType est une chaîne d'indice . L'exemple ci-dessus montre également que les résultats de a.valueOf et a.toString sont tous deux des chaînes, mais « 1,2,3 » est utilisé, ce qui est le résultat de l'utilisation de a.toString. Bien sûr, si nous redéfinissons la méthode toString et renvoyons l'objet, alors la valeur de valueOf sera utilisée :
var a = [1, 2, 3]
a[Symbol.toPrimitive] = function () {
    return 'custom'
}
'' + a // => '' + 'custom' => 'custom'

et "trigger toString" sera d'abord enregistré sur la console, puis "trigger valueOf " sera enregistré. ". Bien entendu, si ces deux objets renvoient des objets, une erreur sera toujours signalée :
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"}

Date
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"}

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn