Compartilhar via


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

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

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

Para obter informações sobre extensões JavaScript do objeto Depurador, consulte Objetos de Depurador Nativos em Extensões JavaScript.

Para obter informações gerais sobre como trabalhar com JavaScript, consulte o Script do Depurador javaScript.

Para scripts e extensões JavaScript, a equipe do depurador mantém um repositório no GitHub em https://github.com/Microsoft/WinDbg-Samples.

Objetos de depurador em extensões JavaScript

Passando objetos nativos

Objetos de 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 de um protótipo JavaScript (como visualizador, por exemplo)
  • Eles podem ser retornados de métodos do host projetados para criar objetos nativos do depurador
  • 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 de objetos nativos do depurador
  • Atributos adicionais

Acesso à propriedade

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

  • Se propertyName for o nome de uma propriedade projetada no objeto pelo próprio provedor JavaScript, ele resolverá isso primeiro; 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 resolverá para este nome como terceira opção; caso contrário
  • Se o objeto for um ponteiro, o ponteiro será desreferenciado e o ciclo acima continuará (uma propriedade projetada do objeto desreferenciado seguido 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, assim como o comando 'dx' faria dentro do depurador.

Nomes projetados

As propriedades (e métodos) a seguir são projetadas em objetos nativos que inserem 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...)
targetLocation 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...)
tamanho do alvo Propriedade Retorna o tamanho do objeto (efetivamente: sizeof(<TYPE OF OBJECT>)
addParentModel .addParentModel(object) Adiciona um novo modelo pai (semelhante a um protótipo javaScript, mas no lado do modelo de dados) ao objeto
removeParentModel .removeParentModel(object) Remove um determinado modelo pai do objeto
objetoTipoTempoDeExecução Propriedade Executa a análise no objeto e tenta convertê-la no tipo runtime (mais derivado)
tipoDestino Propriedade As extensões JavaScript têm acesso direto ao sistema de tipos da linguagem subjacente. Esse acesso é expresso por meio da noção de objetos de tipo. Para obter mais informações, consulte Objetos de Depurador Nativos em Extensões JavaScript – Objetos de Tipo

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(value) Executa a adição matemática de 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)
desreferenciar .dereference() Desreferencia o ponteiro e retorna o objeto subjacente
isNull Propriedade Retorna se o valor do ponteiro é nullptr (0)

Tipos especiais pertencentes a objetos nativos do depurador

Objetos de localização

O objeto de localização 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(value) Adiciona um deslocamento de byte absoluto ao local desejado.
extrair substrato .subtract(value) Subtrai um deslocamento de bytes absoluto 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 de outra forma) que o torne iterável) terá uma função de iterador (indexada por meio do Símbolo.iterador padrão ES6) 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 por meio de ordinais (por exemplo, matrizes nativas) serão indexáveis em JavaScript por meio do operador de acesso à propriedade padrão -- object[index]. Se um objeto for indexável pelo 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 cadeia de caracteres de exibição por meio do suporte de IStringDisplayableConcept ou um elemento NatVis DisplayString terá essa conversão de cadeia de caracteres acessível por meio do método JavaScript toString padrão.

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

Criando objetos de depurador nativos

Conforme mencionado, um script JavaScript pode obter acesso a objetos nativos fazendo com que eles sejam passados para JavaScript de várias maneiras ou podem criá-los por meio de chamadas para a biblioteca de host. Use as funções a seguir para criar objetos nativos do depurador.

Método Assinatura Descrição

host.getModuleSymbol

getModuleSymbol(moduleName, symbolName, [contextInheritor])

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

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

Se o argumento contextInheritor opcional for fornecido, o módulo e o símbolo serão pesquisados no mesmo contexto (espaço de endereço, destino 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 é um script de teste único deve sempre fornecer um contexto explícito.

Se o argumento typeName opcional for fornecido, o símbolo será considerado do tipo passado e o tipo indicado em símbolos 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(location, [contextInheritor])

Retorna 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 contextInheritor opcional for fornecido, o módulo e o símbolo serão pesquisados no mesmo contexto (espaço de endereço, destino 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 é um script de teste único deve sempre fornecer um contexto explícito.

host.createPointerObject

createPointerObject(address, 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 cadeias de caracteres.

Se o argumento contextInheritor opcional for fornecido, o módulo e o símbolo serão pesquisados no mesmo contexto (espaço de endereço, destino 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 é um script de teste único deve sempre fornecer um contexto explícito.

host.createTypedObject

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

Instancia um objeto que representa um objeto de tipo nativo dentro do espaço de endereço de um alvo de depuração em um local especificado. O nome do módulo e o nome do tipo são cadeias de caracteres.

Se o argumento contextInheritor opcional for fornecido, o módulo e o símbolo serão pesquisados no mesmo contexto (espaço de endereço, destino 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 é 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 ele carrega. Esse objeto fornece acesso à funcionalidade crítica para o script, bem como acesso ao namespace do depurador. Ele é configurado em duas fases.

  • Fase 1: antes de qualquer script ser executado, o objeto host contém apenas o conjunto mínimo de funcionalidades necessário para que um script se inicialize e registre seus pontos de extensibilidade (tanto como produtor quanto como 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 for necessário para manipular o estado dos destinos de depuração.

Nível do objeto host

Algumas partes principais da funcionalidade estão diretamente sob o objeto host. O restante é submarcado. Os namespaces incluem o seguinte.

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

Nível de Raiz

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

Nome Assinatura Fase Presente Descrição
createPointerObject

createPointerObject(address, 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 cadeias de caracteres. O argumento contextInheritor opcional funciona como com getModuleSymbol.
criarObjetoTipado

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

2 Instancia um objeto que representa um objeto de tipo nativo dentro do espaço de endereço de um alvo de depuração em um local especificado. O nome do módulo e o nome do tipo são cadeias de caracteres. O argumento contextInheritor opcional funciona como com getModuleSymbol.
currentProcess

Propriedade

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

Propriedade

2 Retorna o objeto que representa a sessão atual do depurador na qual o alvo, despejo, etc., está sendo depurado.
currentThread

Propriedade

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

evaluateExpression(expression, [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 opcional 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, ele será avaliado no contexto atual do depurador
avaliarExpressãoNoContexto

evaluateExpressionInContext(context, expression)

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 ponteiro implícito "this" a ser utilizado para a avaliação. A expressão será avaliada no contexto (por exemplo, espaço de endereço e destino de depuração) indicado pelo argumento de contexto .
getModuleSymbol

getModuleSymbol(moduleName, symbolName, [contextInheritor])

2 Retorna um objeto para um símbolo global em um módulo específico. O nome do módulo e o nome do símbolo são cadeias de caracteres. Se o argumento contextInheritor opcional for fornecido, o módulo e o símbolo serão pesquisados no mesmo contexto (espaço de endereço, destino 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 é um script único deve sempre fornecer um contexto explícito
getNamedModel

getNamedModel(modelName)

2 Retorna o modelo de dados que foi registrado para um nome específico. Observe que é perfeitamente legal chamar isso em relação a um nome que ainda não está registrado. Isso criará um stub para esse nome, e as manipulações do stub serão realizadas no objeto real após o registro.
valorIndexado

new indexedValue(value, í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

new Int64(value, [highValue])

1 Isso constrói um tipo Int64 da biblioteca. A versão de argumento único usará qualquer valor que possa ser empacotado em um Int64 (sem conversão) e o colocará em tal. Se um segundo argumento opcional for fornecido, uma conversão do primeiro argumento será empacotada em 32 bits inferiores e uma conversão do segundo argumento será empacotada nos 32 bits superiores.
namedModelParent

novo 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 classe ES6 como uma extensão pai do modelo de dados de um modelo de dados com o nome fornecido
registroDeModeloNomeado

RegistroNomeadoDoModelo(novo, 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 por meio de um nome conhecido para que outras extensões possam localizar e estender
espaço para nome

Propriedade

2 Fornece acesso direto ao namespace raiz do depurador. É possível, por exemplo, acessar a lista de processos do primeiro destino de depuração por meio de host.namespace.Debugger.Sessions.First(). Processos que usam essa propriedade
registerNamedModel

registerNamedModel(object, modelName)

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

registerExtensionForTypeSignature(object, typeSignature)

2 Isso registra um protótipo JavaScript ou uma 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 de forma imperativa. Qualquer script que faça alterações imperativamente deve ter um método initializeScript para limpeza.
registerPrototypeForTypeSignature

registrarProtótipoParaAssinaturaDeTipo(objeto, assinaturaDeTipo)

2 Isso registra um protótipo JavaScript ou uma 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 de forma imperativa. Qualquer script que faça alterações imperativamente deve ter um método uninitializeScript para limpar.
parseInt64

parseInt64(string, [radix])

1 Esse método atua de forma semelhante ao método padrão JavaScript parseInt, exceto pelo fato de retornar um tipo Int64 da biblioteca. Se um radix for fornecido, a análise ocorrerá na base 2, 8, 10 ou 16, conforme indicado.
Extensão de Assinatura de Tipo

new typeSignatureExtension(object, 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. Esse registro "adiciona campos" à visualização do depurador de qualquer tipo que corresponda à assinatura em vez de tomá-la inteiramente. Um nome de módulo e uma versão opcionais podem restringir o registro. As versões são especificadas como cadeias de caracteres de estilo "1.2.3.4".
RegistroDeAssinaturaDeTipo

new typeSignatureRegistration(object, 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 nativo. Esse registro "assume" a visualização do depurador de qualquer tipo que corresponda à assinatura em vez de apenas estendê-la. Um nome de módulo e uma versão opcionais podem restringir o registro. As versões são especificadas como cadeias de caracteres de estilo "1.2.3.4".
unregisterNamedModel

unregisterNamedModel(modelName)

2 Isso cancela o registro de um modelo de dados da pesquisa pelo nome fornecido, desfazendo qualquer operação executada pelo registerNamedModel
unregisterExtensionForTypeSignature

unregisterExtensionForTypeSignature(object, typeSignature, [moduleName], [minVersion], [maxVersion])

2 Isso cancela o registro de um protótipo JavaScript ou classe ES6 de ser um modelo de dados de extensão para um tipo nativo, conforme fornecido pela assinatura de tipo. É 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 de forma imperativa. Qualquer script que faça alterações imperativamente deve ter um método initializeScript para limpeza. Um nome de módulo e uma versão opcionais podem restringir o registro. As versões são especificadas como cadeias de caracteres de estilo "1.2.3.4".
desregistrarProtótipoParaAssinaturaDeTipo

unregisterPrototypeForTypeSignature(objeto, assinaturaDeTipo, [nomeDoMódulo], [versãoMin], [versãoMax])

2 Isso desregistra um protótipo JavaScript ou classe ES6 de ser o modelo de dados canônico (por exemplo: visualizador) para um tipo nativo, conforme a assinatura de tipo fornecida. É a reversão lógica de registerPrototypeForTypeSignature. Observe que um script deve preferir retornar um objeto typeSignatureRegistration de seu método initializeScript em vez de fazer isso de forma imperativa. Qualquer script que faz alterações imperativamente deve ter um método uninitializeScript para realizar a limpeza. Um nome de módulo e uma versão opcionais podem restringir o registro. 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(object...) 1 Isso fornece debug com estilo printf para uma extensão de script. Atualmente, a saída do 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 roteado para lá no futuro.

Funcionalidade de memória

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

Nome Assinatura Fase Presente Descrição
readMemoryValues

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

2 Isso lê um array bruto de valores do espaço de endereçamento do alvo de depuração e coloca um array tipado sobre a visã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 o tipo) de cada elemento da matriz é fornecido pelos argumentos opcional elementSize e isSigned . Se nenhum desses argumentos for fornecido, o padrão será byte (sem sinal/1 byte). Se o argumento contextInheritor opcional 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, ele será lido do contexto atual do depurador. Observe que o uso desse método em valores de 8, 16 e 32 bits resulta em uma visualização tipada rápida sendo aplicada à memória lida. Usar esse método em valores de 64 bits resulta em uma matriz de tipos de biblioteca de 64 bits sendo construídos, o que é significativamente mais caro!
readString

readString(location, [contextInheritor])

readString(location, [length], [contextInheritor])

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 puder ser lida. O local fornecido pode ser um endereço (um valor de 64 bits), um objeto de localização ou um caractere nativo. Se o argumento contextInheritor opcional 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, ele será lido 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(location, [contextInheritor])

readWideString(location, [length], [contextInheritor])

2 Isso lê uma cadeia de caracteres do tipo wide (UTF-16) do espaço de endereço de um alvo de depuração e retorna o resultado como uma string JavaScript. Ele pode gerar uma exceção se a memória não puder ser lida. O local fornecido pode ser um endereço (um valor de 64 bits), um objeto de localização ou um wchar_t nativo. Se o argumento contextInheritor opcional 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, ele será lido 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 conceitos de modelo de dados a seguir são mapeados para JavaScript.

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

Conversão de string

O conceito de conversão de cadeia de caracteres (IStringDisplayableConcept) é traduzido 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 fornecido em outro lugar), todos os objetos JavaScript retornados ao modelo de dados podem ser convertidos em uma cadeia de caracteres de exibição. Para sobrescrever a conversão de cadeia de caracteres, simplesmente implemente seu próprio método 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 desse tipo tornará o objeto iterável.

Um objeto que só pode ser iterável pode ter uma implementação como a seguir.

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

Deve-se considerar especialmente os 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. Elas podem ser multidimensionais, mas devem corresponder à dimensionalidade retornada no protocolo do 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 o acesso à propriedade e a indexação. Qualquer objeto JavaScript que deseje se apresentar 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 em í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 de runtime

Isso só é relevante para protótipos/classes JavaScript que são registrados com tipos do sistema de tipos nativos. O depurador geralmente é capaz de executar análise (por exemplo, informações de tipo Run-Time (RTTI) / análise de tabela v) para determinar o verdadeiro tipo de tempo de execução de um objeto a partir de um tipo estático expresso no código. Um modelo de dados registrado para um tipo nativo pode modificar este comportamento mediante a implementação do conceito IPreferredRuntimeTypeConcept. Da mesma forma, uma classe JavaScript ou um 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 esse método possa tecnicamente retornar qualquer coisa, ele é considerado uma forma ruim para retornar algo que não é realmente o tipo de runtime ou um tipo derivado. Isso pode resultar em confusão significativa para os usuários do depurador. Sobrescrever este método pode, no entanto, ser valioso para coisas como estilos de cabeçalho mais objeto do tipo C, 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);
    }
}

Consulte também

objetos de depurador nativos em extensões JavaScript

Objetos nativos do depurador em extensões JavaScript – Considerações sobre design e teste

Script do Depurador javaScript

Exemplos de Scripts para Depurador JavaScript