Partilhar via


Objetos do depurador nativo em extensões JavaScript - Detalhes do objeto do depurador

Este tópico descreve detalhes adicionais sobre como usar os objetos de depurador nativos em extensões JavaScript.

Os objetos nativos do depurador representam várias construções e comportamentos do ambiente do depurador. Os objetos podem ser passados para (ou adquiridos em) extensões JavaScript para manipular o estado do depurador.

Para obter informações sobre extensões JavaScript de objeto de depurador, consulte Objetos de depurador nativos em extensões JavaScript.

Para obter informações gerais sobre como trabalhar com JavaScript, consulte JavaScript Debugger Scripting.

Por exemplo, para scripts e extensões JavaScript, a equipa do depurador hospeda o repositório GitHub em https://github.com/Microsoft/WinDbg-Samples.

Objetos do depurador em extensões JavaScript

Passando objetos nativos

Os objetos do depurador podem ser passados ou adquiridos em extensões JavaScript de várias maneiras.

  • Eles podem ser passados para funções ou métodos JavaScript
  • Eles podem ser o objeto de instância para um protótipo JavaScript (como um visualizador, por exemplo)
  • Eles podem ser retornados de métodos de host projetados para criar objetos depuradores nativos
  • Eles podem ser retornados de métodos de host projetados para criar objetos nativos do depurador

Os objetos do depurador que são passados para uma extensão JavaScript têm um conjunto de funcionalidades descrito nesta seção.

  • Acesso à propriedade
  • Nomes projetados
  • Tipos especiais associados a objetos de debugger nativos
  • Atributos adicionais

Acesso à propriedade

Embora existam algumas propriedades em objetos que são colocados lá pelo próprio provedor JavaScript, a maioria das propriedades em um objeto nativo que entra em JavaScript são fornecidas pelo modelo de dados. Isso significa que, para um acesso de propriedade — object.propertyName ou object[propertyName] — ocorrerá o seguinte.

  • Se propertyName for o nome de uma propriedade projetada no objeto pelo próprio provedor JavaScript, esta será a primeira a ser resolvida; caso contrário,
  • Se propertyName for o nome de uma chave projetada no objeto pelo modelo de dados (outro Visualizador), ele será resolvido para esse nome em segundo lugar; caso contrário,
  • Se propertyName for o nome de um campo do objeto nativo, ele será resolvido para esse terceiro nome; caso contrário,
  • Se o objeto for um ponteiro, o ponteiro será desreferenciado e o ciclo acima continuará (uma propriedade projetada do objeto desreferenciado seguida por uma chave seguida por um campo nativo)

Os meios normais de acesso à propriedade em JavaScript -- object.propertyName e object[propertyName] -- acessarão os campos nativos subjacentes de um objeto, da mesma forma que o comando 'dx' dentro do depurador.

Nomes projetados

As seguintes propriedades (e métodos) são projetadas em objetos nativos que entram em JavaScript.

Método Assinatura Descrição
hostContext Propriedade Retorna um objeto que representa o contexto em que o objeto está (o espaço de endereço, o destino de depuração, etc...)
DestinoLocalização Propriedade Retorna um objeto que é uma abstração de onde o objeto está dentro de um espaço de endereço (endereço virtual, registro, sub-registro, etc...)
targetSize Propriedade Retorna o tamanho do objeto (efetivamente: sizeof(<TIPO DE OBJETO>))
addParentModel .addParentModel(objeto) Adiciona um novo modelo pai (semelhante a um protótipo JavaScript, mas no lado do modelo de dados) ao objeto
removeParentModel .removeParentModel(objeto) Remove um determinado modelo pai do objeto
ObjetoTipadoEmTempoDeExecução Propriedade Executa a análise no objeto e tenta convertê-lo para o tipo mais derivado em tempo de execução.
Tipo de destino Propriedade As extensões JavaScript têm acesso direto ao sistema de tipos da linguagem subjacente. Este acesso é expresso através da noção de objetos tipo. Para obter mais informações, consulte Native Debugger Objects in JavaScript Extensions - Type Objects

Se o objeto for um ponteiro, as seguintes propriedades (e métodos) serão projetadas no ponteiro que insere JavaScript:

Nome da propriedade Assinatura Descrição
adicionar .add(valor) Executa a adição matemática do ponteiro entre o ponteiro e o valor especificado
Endereço Propriedade Retorna o endereço do ponteiro como um objeto ordinal de 64 bits (um tipo de biblioteca)
desreferenciação .dereference() Anula a referência do ponteiro e retorna o objeto subjacente
isNull Propriedade Retorna se o valor do ponteiro é ou não nullptr (0)

Tipos especiais pertencentes a objetos de depurador nativos

Objetos de localização

O objeto location que é retornado da propriedade targetLocation de um objeto nativo contém as seguintes propriedades (e métodos).

Nome da propriedade Assinatura Descrição
adicionar .add(valor) Adiciona um deslocamento absoluto de bytes à localização.
subtrair .subtrair(valor) Subtrai um deslocamento absoluto de bytes da posição.

Atributos adicionais

Iterabilidade

Qualquer objeto que seja entendido como iterável pelo modelo de dados (é uma matriz nativa ou tem um visualizador (NatVis ou outro) que o torna iterável) terá uma função iteradora (indexada através do padrão ES6 Symbol.iterator) colocada sobre ele. Isso significa que você pode iterar um objeto nativo em JavaScript da seguinte maneira.

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++.
        //
    }
}

Indexabilidade

Objetos que são entendidos como indexáveis em uma dimensão via ordinais (por exemplo: matrizes nativas) serão indexáveis em JavaScript através do operador de acesso à propriedade padrão -- object[index]. Se um objeto for indexável por nome ou for indexável em mais de uma dimensão, os métodos getValueAt e setValueAt serão projetados no objeto para que o código JavaScript possa utilizar o indexador.

function indexNative(nativeArray)
{
    var first = nativeArray[0];
}

Conversão de String

Qualquer objeto nativo que tenha uma conversão de sequência de exibição através do suporte de IStringDisplayableConcept ou de um elemento DisplayString NatVis terá essa conversão acessível por meio do método padrão toString do JavaScript.

function stringifyNative(nativeObject)
{
    var myString = nativeObject.toString();
}

Criando objetos de depurador nativos

Como mencionado, um script JavaScript pode obter acesso a objetos nativos fazendo-os passar para JavaScript de uma das várias maneiras ou pode criá-los por meio de chamadas para a biblioteca do host. Use as seguintes funções para criar objetos de depurador nativos.

Método Assinatura Descrição

host.getModuleSymbol

getModuleSymbol(moduleName, symbolName, [contextInheritor])

getModuleSymbol(moduleName, symbolName, [typeName], [contextInheritor])

Retorna um objeto para um símbolo global dentro de um módulo específico. O nome do módulo e o nome do símbolo são cadeias de caracteres.

Se o argumento opcional contextInheritor for fornecido, o módulo e o símbolo serão procurados dentro do mesmo contexto (espaço de endereço, destino de depuração) que o objeto fornecido. Se o argumento não for fornecido, o módulo e o símbolo serão pesquisados no contexto atual do depurador. Uma extensão JavaScript que não seja um script de teste único deve sempre fornecer um contexto explícito.

Se o argumento typeName opcional for fornecido, o símbolo será assumido como sendo do tipo passado e o tipo indicado no(s) símbolo(s) será ignorado. Observe que qualquer chamador que espera operar em símbolos públicos para um módulo deve sempre fornecer um nome de tipo explícito.

host.getModuleContainingSymbol

getModuleContainingSymbol(localização, [contextInheritor])

Devolve o símbolo (por exemplo: função ou dados) que contém o endereço fornecido. Observe que isso só funcionará se houver símbolos privados para o módulo que contém o endereço fornecido.

Se o argumento opcional contextInheritor for fornecido, o módulo e o símbolo serão pesquisados dentro do mesmo contexto (espaço de endereço, alvo de depuração) que o objeto passado. Se o argumento não for fornecido, o módulo e o símbolo serão pesquisados no contexto atual do depurador. Uma extensão JavaScript que não seja um script de teste único deve sempre fornecer um contexto explícito.

host.createPointerObject

createPointerObject(endereço, moduleName, typeName, [contextInheritor])

Cria um objeto de ponteiro no endereço ou local especificado. O nome do módulo e o nome do tipo são strings.

Se o argumento opcional contextInheritor for fornecido, o módulo e o símbolo serão pesquisados no mesmo contexto (espaço de endereço, alvo de depuração) que o objeto passado. Se o argumento não for fornecido, o módulo e o símbolo serão pesquisados no contexto atual do depurador. Uma extensão JavaScript que não seja um script de teste único deve sempre fornecer um contexto explícito.

host.createTypedObject

createTypedObject(location, moduleName, typeName, [contextInheritor])

Cria um objeto que representa um objeto tipado nativo dentro do espaço de endereço de um alvo de depuração num local especificado. O nome do módulo e o nome do tipo são strings.

Se o argumento opcional contextInheritor for fornecido, o módulo e o símbolo serão pesquisados dentro do mesmo contexto (espaço de endereço, alvo de depuração) que o objeto passado. Se o argumento não for fornecido, o módulo e o símbolo serão pesquisados no contexto atual do depurador. Uma extensão JavaScript que não seja um script de teste único deve sempre fornecer um contexto explícito.

APIs de host para extensões JavaScript

O provedor JavaScript insere um objeto chamado host no namespace global de cada script que carrega. Este objeto fornece acesso à funcionalidade crítica para o script, bem como acesso ao namespace do depurador. Articula-se em duas fases.

  • Fase 1: Antes de qualquer script ser executado, o objeto host contém apenas o conjunto mínimo de funcionalidades necessárias para que um script se inicialize e registre seus pontos de extensibilidade (como produtor e consumidor). O código raiz e de inicialização não se destina a manipular o estado de um destino de depuração ou executar operações complexas e, como tal, o host não é totalmente preenchido até que o método initializeScript retorne.

  • Fase 2: Depois que initializeScript retorna, o objeto host é preenchido com tudo o que é necessário para manipular o estado dos destinos de depuração.

Nível de objeto do host

Algumas peças-chave de funcionalidade estão diretamente sob o objeto host. O restante é sub-namespaced. Os namespaces incluem o seguinte.

Namespace Descrição
Diagnóstico Funcionalidade para auxiliar no diagnóstico e depuração de código de script
memória Funcionalidade para habilitar a leitura e gravação de memória em um destino de depuração

Nível de raiz

Diretamente no objeto host, as seguintes propriedades, métodos e construtores podem ser encontrados.

Nome Assinatura Fase Presente Descrição
criarObjetoPonteiro

createPointerObject(endereço, moduleName, typeName, [contextInheritor])

2 Cria um objeto de ponteiro no endereço ou local especificado. O nome do módulo e o nome do tipo são strings. O argumento opcional contextInheritor funciona como getModuleSymbol.
criarObjetoTipado

createTypedObject(location, moduleName, typeName, [contextInheritor])

2 Cria um objeto que representa um objeto tipado nativo dentro do espaço de endereço de um alvo de depuração num local especificado. O nome do módulo e o nome do tipo são strings. O argumento opcional contextInheritor funciona como getModuleSymbol.
processo atual

Propriedade

2 Retorna o objeto que representa o processo atual do depurador
sessãoAtual

Propriedade

2 Devolve o objeto que representa a sessão atual do depurador, incluindo o destino, o dump, entre outros, que está a ser depurado.
currentThread

Propriedade

2 Retorna o objeto que representa o thread atual do depurador
evaluateExpression

evaluateExpression(expressão, [contextInheritor])

2 Isso chama o host de depuração para avaliar uma expressão usando apenas o idioma do destino de depuração. Se o argumento contextInheritor for fornecido, a expressão será avaliada no contexto (por exemplo: espaço de endereço e destino de depuração) do argumento; caso contrário, será avaliada no contexto atual do depurador
evaluateExpressionInContext

evaluateExpressionInContext(contexto, expressão)

2 Isso chama o host de depuração para avaliar uma expressão usando apenas o idioma do destino de depuração. O argumento de contexto indica o implícito que este ponteiro deve utilizar para a avaliação. A expressão será avaliada no contexto (por exemplo: espaço de endereço e alvo de depuração) indicado pelo argumento context.
obterSímboloDoMódulo

getModuleSymbol(moduleName, symbolName, [contextInheritor])

2 Retorna um objeto para um símbolo global dentro de um módulo específico. O nome do módulo e o nome do símbolo são cadeias de caracteres. Se o argumento opcional contextInheritor for fornecido, o módulo e o símbolo serão pesquisados dentro do mesmo contexto (espaço de endereço, alvo de depuração) que o objeto passado. Se o argumento não for fornecido, o módulo e o símbolo serão pesquisados no contexto atual do depurador. Uma extensão JavaScript que não seja um script único deve sempre fornecer um contexto explícito
getNamedModel

getNamedModel(nome_modelo)

2 Retorna o modelo de dados que foi registrado em relação a um determinado nome. Note-se que é perfeitamente legal aplicá-lo a um nome que ainda não está registado. Fazer isso criará uma representação para esse nome e as manipulações da representação serão aplicadas ao objeto real no momento do registro.
valor indexado

new indexedValue(valor, índices)

2 Um construtor para um objeto que pode ser retornado de um iterador JavaScript para atribuir um conjunto padrão de índices ao valor iterado. O conjunto de índices deve ser expresso como uma matriz JavaScript.
Int64

novo Int64(value, [highValue])

1 Isso constrói um tipo de biblioteca Int64. A versão com um único argumento aceitará qualquer valor que possa ser embalado num Int64 (sem conversão) e colocará o valor no mesmo. Se um segundo argumento opcional for fornecido, uma conversão do primeiro argumento será empacotada nos 32 bits inferiores e uma conversão do segundo argumento será empacotada nos 32 bits superiores.
nomedModelParent

new namedModelParent(objeto, nome)

1 Um construtor para um objeto destinado a ser colocado na matriz retornada de initializeScript. Isso representa o uso de um protótipo JavaScript ou de uma classe ES6 como extensão de um modelo de dados pai para um modelo de dados com o nome fornecido.
namedModelRegistration

new namedModelRegistration(objeto, nome)

1 Um construtor para um objeto destinado a ser colocado na matriz retornada de initializeScript, isso representa o registro de um protótipo JavaScript ou classe ES6 como um modelo de dados através de um nome conhecido para que outras extensões possam localizar e estender
espaço de nomes

Propriedade

2 Dá acesso direto ao namespace raiz do depurador. Pode-se, por exemplo, acessar a lista de processos do primeiro destino de depuração via host.namespace.Debugger.Sessions.First(). Processos usando esta propriedade
registerNamedModel

registerNamedModel(objeto, modelName)

2 Isso registra um protótipo JavaScript ou classe ES6 como um modelo de dados sob o nome próprio. Tal registro permite que o protótipo ou classe seja localizado e estendido por outros scripts ou outras extensões do depurador. Observe que um script deve preferir retornar um objeto namedModelRegistration de seu método initializeScript em vez de fazer isso imperativamente. Qualquer script que faça alterações imperativamente é necessário ter um método initializeScript para limpar.
registerExtensionForTypeSignature

registerExtensionForTypeSignature(objeto, typeSignature)

2 Isso registra um protótipo JavaScript ou classe ES6 como um modelo de dados de extensão para um tipo nativo, conforme fornecido pela assinatura de tipo fornecida. Observe que um script deve preferir retornar um objeto typeSignatureExtension de seu método initializeScript em vez de fazer isso imperativamente. Qualquer script que faça alterações imperativamente é necessário ter um método initializeScript para limpar.
registerPrototypeForTypeSignature

registerPrototypeForTypeSignature(objeto, typeSignature)

2 Isso registra um protótipo JavaScript ou classe ES6 como o modelo de dados canônico (por exemplo: visualizador) para um tipo nativo, conforme fornecido pela assinatura de tipo fornecida. Observe que um script deve preferir retornar um objeto typeSignatureRegistration de seu método initializeScript em vez de fazer isso imperativamente. Qualquer script que faça alterações imperativamente é necessário ter um método uninitializeScriptpara limpar.
parseInt64

parseInt64(string, [radix])

1 Esse método age de forma semelhante ao método padrão JavaScript parseInt, exceto que ele retorna um tipo Int64 biblioteca em vez disso. Se um radix for fornecido, a análise ocorrerá na base 2, 8, 10 ou 16, conforme indicado.
extensãoDeAssinaturaDeTipo

new typeSignatureExtension(objeto, typeSignature, [moduleName], [minVersion], [maxVersion])

1 Um construtor para um objeto destinado a ser colocado na matriz retornada de initializeScript, isso representa uma extensão de um tipo nativo descrito por meio de uma assinatura de tipo por um protótipo JavaScript ou classe ES6. Tal registo "adiciona campos" à visualização do depurador de qualquer tipo que corresponda à assinatura, em vez de substituí-la completamente. Um nome de módulo opcional e uma versão podem restringir o registo. As versões são especificadas como cadeias de caracteres de estilo "1.2.3.4".
tipoAssinaturaRegistro

new typeSignatureRegistration(objeto, typeSignature, [moduleName], [minVersion], [maxVersion])

1 Um construtor para um objeto destinado a ser colocado na matriz retornada de initializeScript, isso representa um registro canônico de um protótipo JavaScript ou classe ES6 em relação a uma assinatura de tipo nativa. Tal registro toma o controlo da visualização feita pelo depurador de qualquer tipo que corresponda à assinatura, em vez de simplesmente estendê-la. Um nome de módulo opcional e uma versão podem restringir o registo. As versões são especificadas como cadeias de caracteres de estilo "1.2.3.4".
unregisterNamedModel

unregisterNamedModel(modelName)

2 Isso revoga o registo de um modelo de dados para pesquisa pelo nome especificado, desfazendo qualquer operação executada por registerNamedModel
desregistarExtensãoParaAssinaturaDeTipo

unregisterExtensionForTypeSignature(objeto, assinaturaTipo, [nomeMódulo], [versãoMínima], [versãoMáxima])

2 Isso cancela o registo de um protótipo JavaScript ou classe ES6 como modelo de dados de extensão para um tipo nativo, conforme a assinatura de tipo especificada. É o desfazer lógico de registerExtensionForTypeSignature. Observe que um script deve preferir retornar um objeto typeSignatureExtension de seu método initializeScript em vez de fazer isso imperativamente. Qualquer script que faça alterações imperativamente é necessário ter um método initializeScript para limpar. Um nome de módulo opcional e uma versão podem restringir o registo. As versões são especificadas como cadeias de caracteres de estilo "1.2.3.4".
unregisterPrototypeForTypeSignature

unregisterPrototypeForTypeSignature(objeto, typeSignature, [moduleName], [minVersion], [maxVersion])

2 Isso cancela o registro de um protótipo JavaScript ou classe ES6 como modelo de dados canônico (por exemplo: visualizador) para um tipo nativo, conforme a assinatura de tipo fornecida. É a reversão lógica da função registerPrototypeForTypeSignature. Observe que um script deve preferir retornar um objeto typeSignatureRegistration de seu método initializeScript em vez de fazer isso imperativamente. Qualquer script que faça alterações imperativamente é necessário ter um método uninitializeScript para limpar. Um nome de módulo opcional e uma versão podem restringir o registo. As versões são especificadas como cadeias de caracteres de estilo "1.2.3.4".

Funcionalidade de diagnóstico

O subnamespace de diagnóstico do objeto host contém o seguinte.

Nome Assinatura Fase Presente Descrição
debugLog debugLog(objeto...) 1 Isso fornece depuração de estilo printf para uma extensão de script. No momento, a saída de debugLog é roteada para o console de saída do depurador. Em um momento posterior, há planos para fornecer flexibilidade no roteamento dessa saída. Observação : isso não deve ser usado como um meio de imprimir a saída do usuário para o console. Pode não ser encaminhado para lá no futuro.

Funcionalidade de memória

O subnamespace de memória do objeto host contém o seguinte.

Nome Assinatura Fase Presente Descrição
readMemoryValues

readMemoryValues(location, numElements, [elementSize], [isSigned], [contextInheritor])

2 Isso lê uma matriz bruta de valores do espaço de endereço do destino de depuração e coloca uma matriz digitada na parte superior da exibição dessa memória. O local fornecido pode ser um endereço (um valor de 64 bits), um objeto de local ou um ponteiro nativo. O tamanho da matriz é indicado pelo argumento numElements . O tamanho (e tipo) de cada elemento da matriz é dado pelos argumentos opcionais elementSize e isSigned . Se esses argumentos não forem fornecidos, o padrão será byte (não assinado / 1 byte). Se o argumento opcional contextInheritor for fornecido, a memória será lida no contexto (por exemplo: espaço de endereço e destino de depuração) indicado pelo argumento; caso contrário, será lido a partir do contexto atual do depurador. Observe que o uso desse método em valores de 8, 16 e 32 bits resulta em uma exibição digitada rápida sendo colocada sobre a memória de leitura. Usar esse método em valores de 64 bits resulta em uma matriz de tipos de biblioteca de 64 bits sendo construída, o que é significativamente mais caro!
readString

readString(localização, [contextInheritor])

readString(localização, [tamanho], [herdeiroDeContexto])

2 Isso lê uma cadeia de caracteres estreita (página de código atual) do espaço de endereço de um destino de depuração, converte-a em UTF-16 e retorna o resultado como uma cadeia de caracteres JavaScript. Ele pode lançar uma exceção se a memória não pôde ser lida. O local fornecido pode ser um endereço (um valor de 64 bits), um objeto de local ou um char nativo. Se o argumento opcional contextInheritor for fornecido, a memória será lida no contexto (por exemplo: espaço de endereço e destino de depuração) indicado pelo argumento; caso contrário, será lido a partir do contexto atual do depurador. Se o argumento de comprimento opcional for fornecido, a cadeia de caracteres de leitura será do comprimento especificado.
readWideString

readWideString(localização, [contextInheritor])

readWideString(localização, [comprimento], [herdeiroDeContexto])

2 Isso lê uma cadeia de caracteres em formato wide (UTF-16) do espaço de endereço de um alvo de depuração e retorna o resultado como uma cadeia de caracteres JavaScript. Ele pode lançar uma exceção se a memória não pôde ser lida. O local fornecido pode ser um endereço (um valor de 64 bits), um objeto de local ou um wchar_t nativo. Se o argumento opcional contextInheritor for fornecido, a memória será lida no contexto (por exemplo: espaço de endereço e destino de depuração) indicado pelo argumento; caso contrário, será lido a partir do contexto atual do depurador. Se o argumento de comprimento opcional for fornecido, a cadeia de caracteres de leitura será do comprimento especificado.

Conceitos de modelo de dados em JavaScript

Mapeamento de modelo de dados

Os seguintes conceitos de modelo de dados correspondem a JavaScript.

Conceito Interface nativa JavaScript Equivalente
Conversão de cadeia de caracteres IStringDisplayableConcept padrão: toString(...){...}
Iterabilidade IIterableConcept padrão: [Symbol.iterator](){...}
Indexabilidade IIndexableConcept protocolo: getDimensionality(...) / getValueAt(...) / setValueAt(...)
Conversão de tipo de tempo de execução IPreferredRuntimeTypeConcept (conceito de tipo de tempo de execução preferido) protocolo: getPreferredRuntimeTypedObject(...)

Conversão de String

O conceito de transformação de cadeia de caracteres (IStringDisplayableConcept) traduz-se diretamente para o método padrão toString do JavaScript. Como todos os objetos JavaScript têm uma conversão de cadeia de caracteres (fornecida por Object.prototype se não for fornecida em outro lugar), cada objeto JavaScript retornado ao modelo de dados pode ser convertido em uma cadeia de caracteres de exibição. Substituir a conversão de cadeia de caracteres simplesmente requer a implementação de seu próprio toString.

class myObject
{
    //
    // This method will be called whenever any native code calls IStringDisplayableConcept::ToDisplayString(...)
    //
    toString()
    { 
        return "This is my own string conversion!";
    }
}

Iterabilidade

O conceito do modelo de dados de se um objeto é iterável ou não é mapeado diretamente para o protocolo ES6 de se um objeto é iterável. Qualquer objeto que tenha um método [Symbol.iterator] é considerado iterável. A implementação de tal tornará o objeto iterável.

Um objeto que é apenas iterável pode ter uma implementação como a seguinte.

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

Atenção especial deve ser dada para objetos que são iteráveis e indexáveis, pois os objetos retornados do iterador devem incluir o índice, bem como o valor por meio de um tipo de retorno especial.

Iterável e indexável

Um objeto que é iterável e indexável requer um valor de retorno especial do iterador. Em vez de produzir os valores, o iterador produz instâncias de indexedValue. Os índices são passados como uma matriz no segundo argumento para o construtor indexedValue. Eles podem ser multidimensionais, mas devem corresponder à dimensionalidade retornada no protocolo indexador.

Este código mostra um exemplo de implementação.

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]);
    }
}

Indexabilidade

Ao contrário do JavaScript, o modelo de dados faz uma diferenciação muito explícita entre acesso à propriedade e indexação. Qualquer objeto JavaScript que deseje apresentar-se como indexável no modelo de dados deve implementar um protocolo que consiste em um método getDimensionality que retorna a dimensionalidade do indexador e um par opcional de métodos getValueAt e setValueAt que executam leituras e gravações do objeto nos índices fornecidos. É aceitável omitir os métodos getValueAt ou setValueAt se o objeto for somente leitura ou somente gravação

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;
    }
}

Conversão de tipo durante a execução

Isso só é relevante para protótipos/classes JavaScript que são registrados em tipos de sistema de tipo (nativos). O depurador é muitas vezes capaz de executar análises (por exemplo, Run-Time Type Information (RTTI) / v-table analysis) para determinar o verdadeiro tipo de tempo de execução de um objeto a partir de um tipo estático expresso em código. Um modelo de dados registrado em relação a um tipo nativo pode substituir esse comportamento por meio de uma implementação do IPreferredRuntimeTypeConcept. Da mesma forma, uma classe JavaScript ou protótipo registrado em um objeto nativo pode fornecer sua própria implementação por meio da implementação de um protocolo que consiste no método getPreferredRuntimeTypedObject.

Observe que, embora este método possa tecnicamente retornar qualquer coisa, é considerado má prática retornar algo que não seja realmente o tipo em tempo de execução ou um tipo derivado. Isso pode resultar em confusão significativa para os usuários do depurador. Substituir este método pode, no entanto, ser valioso para elementos como cabeçalho estilo C, estilos de implementação de objetos, 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);
    }
}

Ver também

objetos depuradores nativos em extensões JavaScript

Objetos de depurador nativos em extensões JavaScript - Considerações de design e teste

Depuração com Script em JavaScript

Scripts de exemplo do depurador JavaScript