Objets débogueur natifs dans les extensions JavaScript - Détails de l’objet débogueur
Cette rubrique décrit des détails supplémentaires sur l’utilisation des objets débogueur natifs dans les extensions JavaScript.
Les objets débogueur natifs représentent différents constructions et comportements de l’environnement du débogueur. Les objets peuvent être passés dans (ou acquis dans) des extensions JavaScript pour manipuler l’état du débogueur.
Pour plus d’informations sur les extensions JavaScript de l’objet Débogueur, consultez Objets débogueur natifs dans les extensions JavaScript.
Pour obtenir des informations générales sur l’utilisation de JavaScript, consultez Script du débogueur JavaScript.
Par exemple, les scripts et extensions JavaScript, l’équipe de débogueur héberge un dépôt GitHub à l’adresse https://github.com/Microsoft/WinDbg-Samples.
Objets débogueur dans les extensions JavaScript
Passage d’objets natifs
Les objets débogueur peuvent être passés ou acquis dans des extensions JavaScript de différentes façons.
- Elles peuvent être passées à des fonctions ou des méthodes JavaScript
- Ils peuvent être l’objet instance pour un prototype JavaScript (en tant que visualiseur, pour instance)
- Elles peuvent être retournées à partir de méthodes hôtes conçues pour créer des objets de débogueur natifs
- Ils peuvent être retournés à partir de méthodes hôtes conçues pour créer des objets natifs de débogueur
Les objets débogueur passés à une extension JavaScript ont un ensemble de fonctionnalités décrits dans cette section.
- Accès à la propriété
- Noms projetés
- Types spéciaux relatifs aux objets débogueur natifs
- Attributs supplémentaires
Accès à la propriété
Bien qu’il existe certaines propriétés sur les objets qui y sont placées par le fournisseur JavaScript lui-même, la majorité des propriétés d’un objet natif qui entre dans JavaScript sont fournies par le modèle de données. Cela signifie que pour un accès à une propriété --- object.propertyName ou object[propertyName], les éléments suivants se produisent.
- Si propertyName est le nom d’une propriété projetée sur l’objet par le fournisseur JavaScript lui-même, il est résolu en premier ; Sinon
- Si propertyName est le nom d’une clé projetée sur l’objet par le modèle de données (un autre visualiseur), il est résolu en second ; Sinon
- Si propertyName est le nom d’un champ de l’objet natif, il est résolu en ce nom troisième ; Sinon
- Si l’objet est un pointeur, le pointeur est déréférencé et le cycle ci-dessus continue (une propriété projetée de l’objet déréférencement suivi d’une clé suivie d’un champ natif)
Le moyen normal d’accès à la propriété dans JavaScript (object.propertyName et object[propertyName] ) accède aux champs natifs sous-jacents d’un objet, comme le ferait la commande « dx » dans le débogueur.
Noms projetés
Les propriétés (et méthodes) suivantes sont projetées sur des objets natifs qui entrent en JavaScript.
Méthode | Signature | Description |
---|---|---|
hostContext | Propriété | Retourne un objet qui représente le contexte dans lequel se trouve l’objet (l’espace d’adressage, la cible de débogage, etc.) |
targetLocation | Propriété | Retourne un objet qui est une abstraction de l’emplacement où l’objet se trouve dans un espace d’adressage (adresse virtuelle, registre, sous-registre, etc.) |
targetSize | Propriété | Retourne la taille de l’objet (en fait : sizeof(<TYPE OF OBJECT>) |
addParentModel | .addParentModel(object) | Ajoute un nouveau modèle parent (semblable à un prototype JavaScript, mais côté modèle de données) à l’objet |
removeParentModel | .removeParentModel(object) | Supprime un modèle parent donné de l’objet |
runtimeTypedObject | Propriété | Effectue une analyse sur l’objet et tente de le convertir en type runtime (le plus dérivé) |
targetType | Propriété | Les extensions JavaScript ont un accès direct au système de type du langage sous-jacent. Cet accès est exprimé par la notion d’objets de type. Pour plus d’informations, consultez Objets débogueur natifs dans les extensions JavaScript - Objets de type |
Si l’objet est un pointeur, les propriétés (et méthodes) suivantes sont projetées sur le pointeur qui entre en JavaScript :
Nom de la propriété | Signature | Description |
---|---|---|
ajouter | .add(value) | Effectue l’ajout mathématique du pointeur entre le pointeur et la valeur spécifiée |
address | Propriété | Retourne l’adresse du pointeur en tant qu’objet ordinal 64 bits (type de bibliothèque) |
déréférencement | .dereference() | Déréférence le pointeur et retourne l’objet sous-jacent |
Isnull | Propriété | Retourne si la valeur du pointeur est nullptr (0) |
Types spéciaux relatifs aux objets débogueur natifs
Location Objects
L’objet location retourné à partir de la propriété targetLocation d’un objet natif contient les propriétés (et méthodes) suivantes.
Nom de la propriété | Signature | Description |
---|---|---|
ajouter | .add(value) | Ajoute un décalage d’octets absolu à l’emplacement. |
soustraction | .subtract(value) | Soustrait un décalage d’octet absolu de l’emplacement. |
Attributs supplémentaires
Itérabilité
Tout objet qui est compris comme itérable par le modèle de données (il s’agit d’un tableau natif ou d’un visualiseur (NatVis ou autre) qui le rend itérable) a une fonction d’itérateur (indexée via le symbol.iterator standard ES6) placée dessus. Cela signifie que vous pouvez itérer un objet natif en JavaScript comme suit.
function iterateNative(nativeObject)
{
for (var val of nativeObject)
{
//
// val will contain each element iterated from the native object. This would be each element of an array,
// each element of an STL structure which is made iterable through NatVis, each element of a data structure
// which has a JavaScript iterator accessible via [Symbol.iterator], or each element of something
// which is made iterable via support of IIterableConcept in C/C++.
//
}
}
Indexabilité
Les objets qui sont considérés comme indexables dans une dimension via des ordinaux (par exemple, des tableaux natifs) sont indexables en JavaScript via l’opérateur d’accès à la propriété standard - object[index]. Si un objet est indexable par nom ou indexable dans plusieurs dimensions, les méthodes getValueAt et setValueAt sont projetées sur l’objet afin que le code JavaScript puisse utiliser l’indexeur.
function indexNative(nativeArray)
{
var first = nativeArray[0];
}
Conversion de chaîne
Tout objet natif qui a une conversion de chaîne d’affichage via la prise en charge de IStringDisplayableConcept ou d’un élément NatVis DisplayString aura cette conversion de chaîne accessible via la méthode JavaScript toString standard.
function stringifyNative(nativeObject)
{
var myString = nativeObject.toString();
}
Création d’objets débogueur natifs
Comme mentionné, un script JavaScript peut obtenir l’accès aux objets natifs en les faisant passer dans JavaScript de plusieurs façons ou en les créant par le biais d’appels à la bibliothèque hôte. Utilisez les fonctions suivantes pour créer des objets débogueur natifs.
Méthode | Signature | Description |
---|---|---|
host.getModuleSymbol |
getModuleSymbol(moduleName, symbolName, [contextInheritor]) getModuleSymbol(moduleName, symbolName, [typeName], [contextInheritor]) |
Retourne un objet pour un symbole global dans un module particulier. Le nom du module et le nom du symbole sont des chaînes. Si l’argument facultatif contextInheritor est fourni, le module et le symbole sont recherchés dans le même contexte (espace d’adressage, cible de débogage) que l’objet passé. Si l’argument n’est pas fourni, le module et le symbole sont recherchés dans le contexte actuel du débogueur. Une extension JavaScript qui n’est pas un script de test unique doit toujours fournir un contexte explicite. Si l’argument typeName facultatif est fourni, le symbole est supposé être du type passé et le type indiqué dans les symboles est ignoré. Notez que tout appelant qui s’attend à fonctionner sur des symboles publics pour un module doit toujours fournir un nom de type explicite. |
host.getModuleContainingSymbol |
getModuleContainingSymbol(location, [contextInheritor]) | Retourne le symbole (par exemple, fonction ou données) qui contient l’adresse donnée. Notez que cela fonctionne uniquement s’il existe des symboles privés pour le module contenant l’adresse donnée. Si l’argument facultatif contextInheritor est fourni, le module et le symbole sont recherchés dans le même contexte (espace d’adressage, cible de débogage) que l’objet passé. Si l’argument n’est pas fourni, le module et le symbole sont recherchés dans le contexte actuel du débogueur. Une extension JavaScript qui n’est pas un script de test unique doit toujours fournir un contexte explicite. |
host.createPointerObject |
createPointerObject(address, moduleName, typeName, [contextInheritor]) |
Crée un objet pointeur à l’adresse ou à l’emplacement spécifié. Le nom du module et le nom du type sont des chaînes. Si l’argument facultatif contextInheritor est fourni, le module et le symbole sont recherchés dans le même contexte (espace d’adressage, cible de débogage) que l’objet passé. Si l’argument n’est pas fourni, le module et le symbole sont recherchés dans le contexte actuel du débogueur. Une extension JavaScript qui n’est pas un script de test unique doit toujours fournir un contexte explicite. |
host.createTypedObject |
createTypedObject(location, moduleName, typeName, [contextInheritor]) |
Crée un objet qui représente un objet typé natif dans l’espace d’adressage d’une cible de débogage à l’emplacement spécifié. Le nom du module et le nom du type sont des chaînes. Si l’argument facultatif contextInheritor est fourni, le module et le symbole sont recherchés dans le même contexte (espace d’adressage, cible de débogage) que l’objet passé. Si l’argument n’est pas fourni, le module et le symbole sont recherchés dans le contexte actuel du débogueur. Une extension JavaScript qui n’est pas un script de test unique doit toujours fournir un contexte explicite. |
API hôtes pour les extensions JavaScript
Le fournisseur JavaScript insère un objet appelé hôte dans l’espace de noms global de chaque script qu’il charge. Cet objet fournit l’accès aux fonctionnalités critiques du script, ainsi qu’à l’espace de noms du débogueur. Il est mis en place en deux phases.
Phase 1 : avant l’exécution d’un script, l’objet hôte contient uniquement l’ensemble minimal de fonctionnalités nécessaires pour qu’un script s’initialise et enregistre ses points d’extensibilité (à la fois en tant que producteur et consommateur). Le code racine et d’initialisation n’est pas destiné à manipuler l’état d’une cible de débogage ou à effectuer des opérations complexes et, par conséquent, l’hôte n’est entièrement renseigné qu’après le retour de la méthode initializeScript.
Phase 2 : Après le retour initializeScript, l’objet hôte est rempli avec tout ce qui est nécessaire pour manipuler l’état des cibles de débogage.
Niveau de l’objet hôte
Quelques éléments clés de fonctionnalités se trouvent directement sous l’objet hôte. Les autres sont sous-espaces de noms. Les espaces de noms incluent les éléments suivants.
Espace de noms | Description |
---|---|
diagnostics | Fonctionnalités pour faciliter le diagnostic et le débogage du code de script |
mémoire | Fonctionnalité permettant de lire et d’écrire de la mémoire dans une cible de débogage |
Niveau racine
Directement dans l’objet hôte, les propriétés, méthodes et constructeurs suivants sont disponibles.
Nom | Signature | Phase Actuelle | Description |
---|---|---|---|
createPointerObject | createPointerObject(address, moduleName, typeName, [contextInheritor]) |
2 | Crée un objet pointeur à l’adresse ou à l’emplacement spécifié. Le nom du module et le nom du type sont des chaînes. L’argument facultatif contextInheritor fonctionne comme avec getModuleSymbol. |
createTypedObject | createTypedObject(location, moduleName, typeName, [contextInheritor]) |
2 | Crée un objet qui représente un objet typé natif dans l’espace d’adressage d’une cible de débogage à l’emplacement spécifié. Le nom du module et le nom du type sont des chaînes. L’argument facultatif contextInheritor fonctionne comme avec getModuleSymbol. |
currentProcess | Propriété |
2 | Retourne l’objet représentant le processus actuel du débogueur |
currentSession | Propriété |
2 | Retourne l’objet représentant la session actuelle du débogueur (cible, vidage, etc.) en cours de débogage |
currentThread | Propriété |
2 | Retourne l’objet représentant le thread actuel du débogueur |
evaluateExpression | evaluateExpression(expression, [contextInheritor]) |
2 | Cela appelle l’hôte de débogage pour évaluer une expression à l’aide de la langue de la cible de débogage uniquement. Si l’argument facultatif contextInheritor est fourni, l’expression est évaluée dans le contexte (par exemple, espace d’adressage et cible de débogage) de l’argument ; sinon, il sera évalué dans le contexte actuel du débogueur |
evaluateExpressionInContext | evaluateExpressionInContext(context, expression) |
2 | Cela appelle l’hôte de débogage pour évaluer une expression à l’aide de la langue de la cible de débogage uniquement. L’argument de contexte indique l’implicite que ce pointeur doit utiliser pour l’évaluation. L’expression est évaluée dans le contexte (par exemple, espace d’adressage et cible de débogage) indiqué par l’argument de contexte . |
getModuleSymbol | getModuleSymbol(moduleName, symbolName, [contextInheritor]) |
2 | Retourne un objet pour un symbole global dans un module particulier. Le nom du module et le nom du symbole sont des chaînes. Si l’argument facultatif contextInheritor est fourni, le module et le symbole sont recherchés dans le même contexte (espace d’adressage, cible de débogage) que l’objet passé. Si l’argument n’est pas fourni, le module et le symbole sont recherchés dans le contexte actuel du débogueur. Une extension JavaScript qui n’est pas un script unique doit toujours fournir un contexte explicite |
getNamedModel | getNamedModel(modelName) |
2 | Retourne le modèle de données qui a été inscrit par rapport à un nom donné. Notez qu’il est parfaitement légal d’appeler cela contre un nom qui n’est pas encore enregistré. Cela créera un stub pour ce nom et les manipulations du stub seront effectuées sur l’objet réel lors de l’inscription. |
indexedValue | new indexedValue(value, indicies) |
2 | Constructeur pour un objet qui peut être retourné à partir d’un itérateur JavaScript afin d’affecter un jeu d’indices par défaut à la valeur itérée. L’ensemble d’indics doit être exprimé sous la forme d’un tableau JavaScript. |
Int64 | new Int64(value, [highValue]) |
1 | Cela construit une bibliothèque de type Int64. La version à argument unique prend n’importe quelle valeur pouvant être empaqueté dans un Int64 (sans conversion) et la place dans celle-ci. Si un deuxième argument facultatif est fourni, une conversion du premier argument est empaquetée dans les 32 bits inférieurs et une conversion du deuxième argument est empaquetée dans les 32 bits supérieurs. |
namedModelParent | new namedModelParent(object, name) |
1 | Constructeur pour un objet destiné à être placé dans le tableau retourné par initializeScript, il s’agit de l’utilisation d’un prototype JavaScript ou d’une classe ES6 comme extension parente de modèle de données d’un modèle de données portant le nom donné |
namedModelRegistration | new namedModelRegistration(object, name) |
1 | Constructeur pour un objet destiné à être placé dans le tableau retourné par initializeScript, qui représente l’inscription d’un prototype JavaScript ou d’une classe ES6 en tant que modèle de données via un nom connu afin que d’autres extensions puissent trouver et étendre |
espace de noms | Propriété |
2 | Donne un accès direct à l’espace de noms racine du débogueur. Par exemple, vous pouvez accéder à la liste de processus de la première cible de débogage via host.namespace.Debugger.Sessions.First(). Processus utilisant cette propriété |
registerNamedModel | registerNamedModel(object, modelName) |
2 | Cela inscrit un prototype JavaScript ou une classe ES6 en tant que modèle de données sous le nom donné. Une telle inscription permet au prototype ou à la classe d’être localisé et étendu par d’autres scripts ou d’autres extensions de débogueur. Notez qu’un script doit préférer retourner un objet namedModelRegistration à partir de sa méthode initializeScript plutôt que de le faire de manière impérative. Tout script qui apporte des modifications impérativement doit avoir une méthode initializeScript pour propre. |
registerExtensionForTypeSignature | registerExtensionForTypeSignature(object, typeSignature) |
2 | Cela inscrit un prototype JavaScript ou une classe ES6 en tant que modèle de données d’extension pour un type natif, comme indiqué par la signature de type fournie. Notez qu’un script doit préférer retourner un objet typeSignatureExtension à partir de sa méthode initializeScript plutôt que de procéder de manière impérative. Tout script qui apporte des modifications impérativement doit avoir une méthode initializeScript pour propre. |
registerPrototypeForTypeSignature | registerPrototypeForTypeSignature(object, typeSignature) |
2 | Cela inscrit un prototype JavaScript ou une classe ES6 en tant que modèle de données canonique (par exemple, visualiseur) pour un type natif tel qu’indiqué par la signature de type fournie. Notez qu’un script doit préférer retourner un objet typeSignatureRegistration à partir de sa méthode initializeScript plutôt que de procéder de manière impérative. Tout script qui apporte des modifications de manière impérative doit avoir une méthode uninitializeScriptpour propre. |
parseInt64 | parseInt64(string, [radix]) |
1 | Cette méthode agit de la même façon que la méthode parseInt JavaScript standard, sauf qu’elle retourne un type Int64 de bibliothèque à la place. Si un radix est fourni, l’analyse se produit en base 2, 8, 10 ou 16 comme indiqué. |
typeSignatureExtension | new typeSignatureExtension(object, typeSignature, [moduleName], [minVersion], [maxVersion]) |
1 | Constructeur d’un objet destiné à être placé dans le tableau retourné par initializeScript, il s’agit d’une extension d’un type natif décrit via une signature de type par un prototype JavaScript ou une classe ES6. Une telle inscription « ajoute des champs » à la visualisation du débogueur de tout type qui correspond à la signature au lieu de la reprendre entièrement. Un nom et une version de module facultatifs peuvent restreindre l’inscription. Les versions sont spécifiées en tant que chaînes de style « 1.2.3.4 ». |
typeSignatureRegistration | new typeSignatureRegistration(object, typeSignature, [moduleName], [minVersion], [maxVersion]) |
1 | Constructeur pour un objet destiné à être placé dans le tableau retourné par initializeScript, il s’agit d’une inscription canonique d’un prototype JavaScript ou d’une classe ES6 par rapport à une signature de type native. Une telle inscription « prend le relais » de la visualisation du débogueur de tout type qui correspond à la signature au lieu de simplement l’étendre. Un nom et une version de module facultatifs peuvent restreindre l’inscription. Les versions sont spécifiées en tant que chaînes de style « 1.2.3.4 ». |
unregisterNamedModel | unregisterNamedModel(modelName) |
2 | Cette opération annule l’inscription d’un modèle de données de la recherche par le nom donné, annulant toute opération effectuée par registerNamedModel. |
unregisterExtensionForTypeSignature | unregisterExtensionForTypeSignature(object, typeSignature, [moduleName], [minVersion], [maxVersion]) |
2 | Cela annule l’inscription d’un prototype JavaScript ou d’une classe ES6 d’un modèle de données d’extension pour un type natif tel qu’indiqué par la signature de type fournie. Il s’agit de l’annulation logique de registerExtensionForTypeSignature. Notez qu’un script doit préférer retourner un objet typeSignatureExtension à partir de sa méthode initializeScript plutôt que de procéder de manière impérative. Tout script qui apporte des modifications impérativement doit avoir une méthode initializeScript pour propre. Un nom et une version de module facultatifs peuvent restreindre l’inscription. Les versions sont spécifiées en tant que chaînes de style « 1.2.3.4 ». |
unregisterPrototypeForTypeSignature | unregisterPrototypeForTypeSignature(object, typeSignature, [moduleName], [minVersion], [maxVersion]) |
2 | Cela annule l’inscription d’un prototype JavaScript ou d’une classe ES6 en tant que modèle de données canonique (par exemple, visualiseur) pour un type natif tel qu’indiqué par la signature de type fournie. Il s’agit de l’annulation logique de registerPrototypeForTypeSignature. Notez qu’un script doit préférer retourner un objet typeSignatureRegistration à partir de sa méthode initializeScript plutôt que de procéder de manière impérative. Tout script qui apporte des modifications de manière impérative doit avoir une méthode unnitializeScript pour propre. Un nom et une version de module facultatifs peuvent restreindre l’inscription. Les versions sont spécifiées en tant que chaînes de style « 1.2.3.4 ». |
Fonctionnalité de diagnostic
Le diagnostics sous-espace de noms de l’objet hôte contient les éléments suivants.
Nom | Signature | Phase Actuelle | Description |
---|---|---|---|
debugLog | debugLog(object...) | 1 | Cela permet de déboguer le style printf sur une extension de script. Actuellement, la sortie de debugLog est routée vers la console de sortie du débogueur. À un moment ultérieur, il est prévu d’offrir une flexibilité sur le routage de cette sortie. REMARQUE : Il ne doit pas être utilisé comme moyen d’imprimer la sortie de l’utilisateur dans la console. Il ne sera peut-être pas acheminé là-bas à l’avenir. |
Fonctionnalité de mémoire
Le sous-espace de noms mémoire de l’objet hôte contient les éléments suivants.
Nom | Signature | Phase Actuelle | Description |
---|---|---|---|
readMemoryValues | readMemoryValues(location, numElements, [elementSize], [isSigned], [contextInheritor]) |
2 | Cela lit un tableau brut de valeurs à partir de l’espace d’adressage de la cible de débogage et place un tableau typé sur la vue de cette mémoire. L’emplacement fourni peut être une adresse (valeur 64 bits), un objet location ou un pointeur natif. La taille du tableau est indiquée par l’argument numElements . La taille (et le type) de chaque élément du tableau sont données par les arguments facultatifs elementSize et isSigned . Si aucun argument de ce type n’est fourni, la valeur par défaut est octet (non signé / 1 octet). Si l’argument facultatif contextInheritor est fourni, la mémoire est lue dans le contexte (par exemple , espace d’adressage et cible de débogage) indiqué par l’argument ; sinon, elle sera lue à partir du contexte actuel du débogueur. Notez que l’utilisation de cette méthode sur les valeurs 8, 16 et 32 bits entraîne la mise en place d’une vue typée rapide sur la mémoire de lecture. L’utilisation de cette méthode sur des valeurs 64 bits entraîne la construction d’un tableau de types de bibliothèques 64 bits, ce qui est beaucoup plus coûteux! |
readString | readString(location, [contextInheritor]) readString(location, [length], [contextInheritor]) |
2 | Cette opération lit une chaîne étroite (page de codes actuelle) à partir de l’espace d’adressage d’une cible de débogage, la convertit en UTF-16 et retourne le résultat sous la forme d’une chaîne JavaScript. Il peut lever une exception si la mémoire n’a pas pu être lue. L’emplacement fourni peut être une adresse (valeur 64 bits), un objet location ou un caractère natif. Si l’argument facultatif contextInheritor est fourni, la mémoire est lue dans le contexte (par exemple , espace d’adressage et cible de débogage) indiqué par l’argument ; sinon, elle sera lue à partir du contexte actuel du débogueur. Si l’argument de longueur facultatif est fourni, la chaîne de lecture est de la longueur spécifiée. |
readWideString | readWideString(location, [contextInheritor]) readWideString(location, [length], [contextInheritor]) |
2 | Cette opération lit une chaîne large (UTF-16) à partir de l’espace d’adressage d’une cible de débogage et retourne le résultat sous la forme d’une chaîne JavaScript. Il peut lever une exception si la mémoire n’a pas pu être lue. L’emplacement fourni peut être une adresse (valeur 64 bits), un objet location ou un wchar_t natif. Si l’argument facultatif contextInheritor est fourni, la mémoire est lue dans le contexte (par exemple , espace d’adressage et cible de débogage) indiqué par l’argument ; sinon, elle sera lue à partir du contexte actuel du débogueur. Si l’argument de longueur facultatif est fourni, la chaîne de lecture est de la longueur spécifiée. |
Concepts du modèle de données en JavaScript
Mappage de modèle de données
Les concepts de modèle de données suivants sont mappés à JavaScript.
Concept | Native Interface | Équivalent JavaScript |
---|---|---|
Conversion de chaîne | IStringDisplayableConcept | standard : toString(...) {...} |
Itérabilité | IIterableConcept | standard : [Symbol.iterator](){...} |
Indexabilité | IIndexableConcept | protocole : getDimensionality(...) / getValueAt(...) / setValueAt(...) |
Runtime Type Conversion | IPreferredRuntimeTypeConcept | protocole : getPreferredRuntimeTypedObject (...) |
Conversion de chaîne
Le concept de conversion de chaîne (IStringDisplayableConcept) se traduit directement par la méthode javaScript toString standard. Comme tous les objets JavaScript ont une conversion de chaîne (fournie par Object.prototype s’il n’est pas fourni ailleurs), chaque objet JavaScript retourné au modèle de données peut être converti en chaîne d’affichage. Le remplacement de la conversion de chaîne nécessite simplement l’implémentation de votre propre toString.
class myObject
{
//
// This method will be called whenever any native code calls IStringDisplayableConcept::ToDisplayString(...)
//
toString()
{
return "This is my own string conversion!";
}
}
Itérabilité
Le concept du modèle de données qui détermine si un objet est itérable ou non mappe directement au protocole ES6, indiquant si un objet est itérable. Tout objet qui a une méthode [Symbol.iterator] est considéré comme itérable. L’implémentation de ce type rend l’objet itérable.
Un objet qui n’est itérable que peut avoir une implémentation telle que la suivante.
class myObject
{
//
// This method will be called whenever any native code calls IIterableConcept::GetIterator
//
*[Symbol.iterator]()
{
yield "First Value";
yield "Second Value";
yield "Third Value";
}
}
Une attention particulière doit être accordée aux objets qui sont à la fois itérables et indexables, car les objets retournés par l’itérateur doivent inclure l’index ainsi que la valeur via un type de retour spécial.
Itérable et indexable
Un objet itérable et indexable nécessite une valeur de retour spéciale de l’itérateur. Au lieu de produire les valeurs, l’itérateur génère des instances d’indexedValue. Les indicies sont passées en tant que tableau dans le deuxième argument au constructeur indexedValue. Ils peuvent être multidimensionnels, mais doivent correspondre à la dimensionnalité retournée dans le protocole de l’indexeur.
Ce code montre un exemple d’implémentation.
class myObject
{
//
// This method will be called whenever any native code calls IIterableConcept::GetIterator
//
*[Symbol.iterator]()
{
//
// Consider this a map which mapped 42->"First Value", 99->"Second Value", and 107->"Third Value"
//
yield new host.indexedValue("First Value", [42]);
yield new host.indexedValue("Second Value", [99]);
yield new host.indexedValue("Third Value", [107]);
}
}
Indexabilité
Contrairement à JavaScript, le modèle de données fait une distinction très explicite entre l’accès aux propriétés et l’indexation. Tout objet JavaScript qui souhaite se présenter comme indexable dans le modèle de données doit implémenter un protocole constitué d’une méthode getDimensionality qui retourne la dimensionnalité de l’indexeur et d’une paire facultative de méthodes getValueAt et setValueAt qui effectuent des lectures et des écritures de l’objet aux indices fournis. Il est acceptable d’omettre les méthodes getValueAt ou setValueAt si l’objet est en lecture seule ou en écriture seule
class myObject
{
//
// This method will be called whenever any native code calls IIndexableConcept::GetDimensionality or IIterableConcept::GetDefaultIndexDimensionality
//
getDimensionality()
{
//
// Pretend we are a two dimensional array.
//
return 2;
}
//
// This method will be called whenever any native code calls IIndexableConcept::GetAt
//
getValueAt(row, column)
{
return this.__values[row * this.__columnCount + column];
}
//
// This method will be called whenever any native code calls IIndexableConcept::SetAt
//
setValueAt(value, row, column)
{
this.__values[row * this.__columnCount + column] = value;
}
}
Runtime Type Conversion
Cela s’applique uniquement aux prototypes/classes JavaScript qui sont inscrits sur des types de système de type (natifs). Le débogueur est souvent capable d’effectuer une analyse (par exemple, Run-Time analyse des informations de type (RTTI) / v-table) pour déterminer le type d’exécution réel d’un objet à partir d’un type statique exprimé en code. Un modèle de données inscrit sur un type natif peut remplacer ce comportement via une implémentation de IPreferredRuntimeTypeConcept. De même, une classe JavaScript ou un prototype inscrit sur un objet natif peut fournir sa propre implémentation via l’implémentation d’un protocole constitué de la méthode getPreferredRuntimeTypedObject.
Notez que bien que cette méthode puisse techniquement retourner n’importe quoi, elle est considérée comme une mauvaise forme pour retourner quelque chose qui n’est pas vraiment le type d’exécution ou un type dérivé. Cela peut entraîner une confusion importante pour les utilisateurs du débogueur. Toutefois, la substitution de cette méthode peut être utile pour des choses telles que l’en-tête de style C +les styles d’objet d’implémentation, etc...
class myNativeModel
{
//
// This method will be called whenever the data model calls IPreferredRuntimeTypeConcept::CastToPreferredRuntimeType
//
getPreferredRuntimeTypedObject()
{
var loc = this.targetLocation;
//
// Perform analysis...
//
var runtimeLoc = loc.Add(runtimeObjectOffset);
return host.createTypedObject(runtimeLoc, runtimeModule, runtimeTypeName);
}
}
Voir aussi
Objets débogueur natifs dans les extensions JavaScript