Passando toSource em uma solução completa de serialização

ProblemaVocê quer uma correção para transformar toSource em uma solução de serialização completa. Teoria da Mozilla desenvolveu um método muito inteligente chamado toSource. Usando toSource, é possível serializar o estado de um objeto em um buffer. Considere o exemplo a seguinte declaração de tipo.

 Fonte: / website / ROOT / artigos ajax / javascript / DefinedClass função tosource.html () (this.localvalue = 10; this.localmethod = function (param) (info ( "DefinedClass.localmethod", "chamou-me");))

O tipo DefinedClass foi definido um método localmethod e um membro de dados localvalue. Quando o tipo é instanciado, o tipo instanciado toSource tem um método que pode ser chamado, como ilustrado no seguinte código-fonte.

 Fonte: / website / ROOT / artigos ajax / javascript / tosource.html cls DefinedClass var = new (); cls.prototypemethod.value = 100; info (mozilla_tosource ", cls.toSource ());

Quando toSource é chamada, o buffer é gerada a seguinte:

(Localvalue: 10, localmethod: (function (param) (info ( "DefinedClass.localmethod", "me chamou ");}))

O buffer gerado é uma forma serializada de uma instância do objeto. Ausente da serialização é a definição do tipo. Quando a instância do objeto é re-criado, recriado é o estado do objeto. No entanto, isto não é completamente verdade, porque a declaração seguinte protótipo é perdida por toSource.

 Fonte: / website / ROOT / artigos ajax / javascript / tosource.html DefinedClass.prototype.prototypevalue StaticClass = new ();
  

Tudo o que é declarado através da propriedade DefinedClass.prototype é perdida pela implementação toSource. Faltando as propriedades de base e métodos faz sentido se o buffer toSource foram para conter uma referência ao tipo que criou a instância. Ainda não há nenhuma referência com a falta de métodos e propriedades, e sem apoio em qualquer outro navegador do Mozilla / Firefox. Então, o que é o uso de toSource? O método toSource por si só é limitada, mas a idéia por trás toSource é bom. Queremos a capacidade de serializar um objeto para consumo posterior, e como será mostrado em artigos posteriores, serialização é a chave para a implementação objeto-orientado diversas técnicas, tais como mixins. Conforme ilustrado pela implementação de Mozilla de toSource, serialização pode ter diferentes facetas . Antes de iniciar uma aplicação de serialização, vamos identificar os diferentes contextos de serialização:

Plain vanilla como serialização toSource: A serialização padrão fornecido pela Mozilla não está disponível em outros navegadores. Para essas aplicações Web que não toSource utilização, é necessário que haja uma implementação para outros navegadores. Não serializar as propriedades do protótipo é útil quando você desejar para serializar as informações adicionais e não a informação de base.

Completamente serialização declaração de instância: Um exemplo de serialização é completo quando todos os métodos, propriedades e membros de dados são convertidos em uma reserva que, quando executado, irá recriar completamente o objeto. Quando a instância é re-criado, o seu tipo de informação original é perdida.

Instância serialização estado: Em contraste com outros serializações, serialização do estado é a geração de uma reserva que contém apenas o estado de um objeto, a função declarações não são gerados. O JavaScript Object Notation (JSON) protocolo é um exemplo de um estado da instância serialização somente. Quando serializar o estado da instância, membros de dados definido na propriedade protótipo estão incluídos.

Serialização atribuição Variável: Um exemplo de serialização declaração completa inclui todo o estado de uma instância do objeto, mas as propriedades da função estão em falta porque não usavam com freqüência. Se uma propriedade função é usada, então o estado serializado deve ser atribuído a uma variável, caso contrário, é muito difícil atribuir propriedades função.

Object-oriented serialização: Serialização orientada a objeto é uma extensão da serialização plain vanilla. A razão para a definição de um objeto de serialização é orientado para permitir a separação de classes de dados específicos e dados de instância específica. Usando serialização objectoriented, um objeto pode ser serializado e recriada com o comportamento padrão diferente. Cada um dos contextos é um tipo específico de serialização. A característica comum entre todos os contextos é que serializar as mesmas informações e filtrar o que não é necessário. Por exemplo, os filtros de "plain vanilla" serialização qualquer propriedade referenciada pelo protótipo. Filtros de serialização Estado todas as funções, mas reitera propriedades referenciadas pelo protótipo. Solução Como primeiro passo, vamos criar uma geral "serializar tudo" de implementação. A implementação serializar tudo vai incluir capacidades de filtragem e capacidades de saída de controle de geração. Usando a serialização geral requer um pouco de compreensão do processo de serialização, de modo que ajuste fino é possível. Numa segunda fase, vamos implementar a serialização contextos específicos com as implementações de filtragem apropriada.

A serialização significa tudo iteração tudo que está armazenado na instância do objeto e, em seguida, pedir ao interlocutor se ele está OK para serializar as informações. De um nível elevado, a função serialize tudo é implementado como se segue. Na funcionalidade serializar tudo, duas peças de funcionalidade foram cortadas por razões de clareza e são anotadas pelos comentários

/ / Removido para maior clareza. Fonte: / website / root / scripts / Common.js serializar: function (obj, chamadas de retorno) (var buffer = "("; vírgula var = function () (vírgula = function () (return ",";) return "";) quoteProperties var = ""; canProcessFilter var = function () (return true;) functionPropertyCallback var = function () (var) callingStack if (typeof (arguments [2]) == "undefined") (callingStack = new Array () ; callingStack.push ( "cls");) else (argumentos callingStack = [2];) if (callbacks) (/ / Removidos para maior clareza) for (propriedade em obj) (if (canProcessFilter (obj [property], obj property)) (switch (typeof (obj propriedade [])) (/ / Removidos para maior clareza))) buffer + = ")" return buffer;)

O serializar função tem dois parâmetros, mas para certos contextos (explicado mais tarde), há um terceiro parâmetro. O terceiro parâmetro foi deixado fora de modo a não confundir as pessoas que querem usar a função. O primeiro parâmetro, obj, representa a instância do objeto que será serializado. O segundo parâmetro, callbacks, representa os métodos de personalização que são chamados quando os dados são serializados. Até o laço é iniciado usando a palavra-chave para as variáveis são inicializadas. Eles são definidos como segue:

• buffer: Essa variável é usada para criar o texto completo que representa o objeto serializado.

• vírgula: Esta variável utiliza a técnica descrita no artigo 2-7 para determinar se uma vírgula é necessária para criar o JavaScript formato serializado objeto. Como referência, cada declaração de propriedade em um formato serializado objeto (por exemplo, (prop1: true;, prop2: false)) é separado com uma vírgula. A função implementa uma técnica onde a primeira vez que é chamado, nenhuma vírgula é necessária, mas para cada chamada, posteriormente, uma vírgula é necessária. Sem usar a técnica no artigo 2-7, um bloco de decisão ea bandeira seria necessário.

QuoteProperties •: Esta variável indica se o buffer contém um aspas duplas. A citação é usada quando serializar o objeto em formato JSON.

CanProcessFilter •: Essa variável é uma função callback que é chamado para cada valor da propriedade encontrada. O callback retorna true para serializar a propriedade ou falso para ignorar a propriedade. O callback tem três parâmetros: a propriedade, a referência da propriedade real; obj, o objeto a ser serializado e PropertyIdentifier, o identificador de seqüência de caracteres da propriedade.

FunctionPropertyCallback •: Essa variável é uma função callback que é chamado quando a iteração das propriedades de uma função. As propriedades da função não pode ser armazenado na variável buffer serializado porque o formato não permite a definição das propriedades da função. As propriedades de uma função deve ser atribuída após a definição da reserva serializado objeto JavaScript. É por isso que a serialização completa de um objeto JavaScript exige uma definição variável.

CallingStack •: Para atribuir uma propriedade função incorporada dentro de outra declaração de objeto de JavaScript, você precisa do objeto serializado referência (por exemplo, variable.embeddedobj function.value.). Para criar a referência, uma pilha é utilizada, onde cada elemento da pilha é uma referência de objeto. Após as declarações, as propriedades do objeto são iteradas (para (property. ..) em um loop. Antes de explicar os detalhes da loop, eu vou cobrir a inicialização chamada falta.

 Fonte: / website / root / scripts / Common.js if (callbacks) (if (callbacks.canProcessFilter) (canProcessFilter callbacks.canProcessFilter =;) if (callbacks.functionPropertyCallback) (functionPropertyCallback callbacks.functionPropertyCallback =;) if (callbacks.variablename) ( callingStack.pop (); callingStack.push (callbacks.variablename);) if (callbacks.quoteProperties) (if (callbacks.quoteProperties == true) (quoteProperties = "\";)))

O chamador da serialização não precisa fornecer um valor para callbacks. Se nenhum valor for fornecido, uma serialização padrão de tudo é assumido, exceto as propriedades da função. As propriedades da função não são serializado porque não há nenhuma maneira no formato serializado objeto JavaScript de propriedade associar uma função com a função. Mais do código será explicado em breve. A serialização tem quatro funções de retorno:

• canProcessFilter: Utilizado para determinar se a propriedade pode ser serializado.

FunctionPropertyCallback •: Chamada sempre que uma propriedade função é serializado.

• variableName: Representa o identificador de variável utilizada quando uma serialização de uma variável é gerada.

• quoteProperties: Representa um valor que, quando definido como true gera aspas em torno do identificador de propriedade. Isto é tipicamente usado ao gerar um formato de serialização JSON. Agora que já olhou os detalhes de inicialização, vamos passar a examinar a lógica de serialização. O ciclo é responsável pela serialização a instância do objeto, e os detalhes do circuito ter sido abreviado. Nesta fase, eu vou explicar a estratégia global. Em JavaScript, cada método e membro de dados podem ser acessados em um objeto usando a notação seguinte:

obj.datamember = ...

Esta notação é a forma mais comum de acessar um método ou membro de dados quando se escreve o código-fonte. Para fins de serialização não, a notação é útil porque o programador deve saber o que os métodos individuais e membros de dados são. Para fins de serialização, a reflexão é necessária. Reflexão em JavaScript é um processo de duas etapas:

1. A seqüência de caracteres identificadores valor da propriedade estão disponíveis através de uma enumeração e iteradas usando um loop (por exemplo, for (em propriedade obj)).

2. A propriedade real é acessado usando uma notação de matriz, onde a matriz é a instância do objeto e do índice é o string identificador propriedade de valor (por exemplo, obj [propriedade]).

À medida que cada propriedade é iterativo, a serialização consultas de primeira, se a propriedade deve ser serializado, chamando a função de retorno canProcessFilter. Se a propriedade pode ser serializado, em seguida, uma instrução switch é chamado de que testa o tipo do imóvel. A função retorna typeof seis identificadores diferentes, dos quais cinco são de interesse (não estamos interessados em indefinido, como indefinidas não deve ser serializado). Os detalhes do comando switch são os seguintes.

 Fonte: / website / root / scripts / Common.js switch (typeof (obj propriedade [])) (case "boolean": buffer + = vírgula () + + quoteProperties propriedade quoteProperties + + ":" + object [propriedade] break; função de "caso": buffer + = vírgula () + + quoteProperties propriedade quoteProperties + + ":" + obj [propriedade]. toString (); callingStack.push (propriedade); functionPropertyCallback (obj propriedade [] callbacks obj, propriedade , callingStack); callingStack.pop () break; caso "número": buffer + = vírgula () + + quoteProperties propriedade quoteProperties + + ":" + obj [propriedade] break;; objeto "caso": callingStack.push ( propriedade); buffer + = vírgula () + + quoteProperties propriedade quoteProperties + + ":" + ops.serialize (obj propriedade [], callbacks, callingStack); callingStack.pop () break; string "caso": buffer + = vírgula () + + quoteProperties propriedade quoteProperties + + ":" + object [propriedade] break;)

Na execução da instrução switch, o número de tipos, string, boolean e têm uma implementação de serialização simples. A serialização dos tipos seguem a convenção [identificador propriedade]: [valor da propriedade]. função e objeto são mais complicadas. Quando um objeto é encontrado, em seguida, uma serialização objeto incorporado JavaScript ocorre ops.serialization ea função é chamada recursivamente. O resultado da serialização é um valor da propriedade que é adicionado à reserva para ser devolvido para o chamador. As restantes partes do serializar função adicionar um colchete curvas para fechar a serialização e devolver o buffer gerado para o chamador. A serialização apresentada está completa, e cada um dos contextos usa a função de serialização para gerar sua própria reserva gerada. Vamos considerar o implementação da função Serializer.toSource, que imita a serialização toSource Mozilla. Isto significa que qualquer função ou membro de dados definidos como parte da propriedade do protótipo não é processado. O que está sendo pedido é para determinar se uma propriedade deve ser serializado usando um filtro. A implementação completa do Serializer.toSource segue.

 Fonte: / website / root / scripts / Jaxson / commons.js Serializer.toSource = function (obj) (return ops.serialize (obj, (currProcessedObject: null, iterPrototype: null, canProcessFilter: function (propriedade, currObj, PropertyIdentifier) (if ( this.currProcessed! = currObj) (GetPrototypeObject (currObj, função (protótipo) = (this.iterPrototype protótipo;)); this.currProcessed = currObj;) if (typeof iterPrototype () == "object") (for (em prototypeIdentifier iterPrototype) (if (prototypeIdentifier == PropertyIdentifier) (return false;))) return true;)));)

Na execução do Serialize.

toSource é uma única chamada de método, e é para ops.serialize. Por padrão, ops.serialize irá serializar tudo, e que deve ser evitado. Para ser capaz de distinguir entre uma propriedade de instância e uma propriedade definida pela propriedade do protótipo, a implementação de canProcessFilter tem de descobrir quais propriedades estão associadas com a instância. Na implementação do método canProcessFilter é uma referência ao GetPrototypeObject. GetPrototypeObject é uma conveniência função utilizada para recuperar a propriedade prototype associado com o objeto. Eu cubro a implementação de GetPrototypeObject breve. No momento, vamos nos concentrar no que acontece no filtro. Quando ops.serialize é chamado, ele irá percorrer as propriedades do toSerialize objeto. Quando um imóvel é recuperado, a função canFilterProcess UserDefined filtro é chamado. canFilterProcess tem como parâmetro segundo o objeto ao qual o logo-a-ser-serializado propriedade pertence.

 Fonte: / website / root / scripts / Jaxson / commons.js função GetPrototypeObject (obj, callback) (if (typeof (obj.constructor) == "function") (var = funcMatch / função \ s (.*) \ (/; Var result = obj.constructor.toString (). Fósforo (funcMatch); if (resultado! = Null) (if (typeof (retorno) == "function") (var iterobj if (typeof (resultado [1]) == "string") (eval (prototypePropery "var =" + resultado [1] + "protótipo.;"); callback (prototypePropery, resultado [1]);)))))

Na execução do GetPrototypeObject, o primeiro teste é a verificação de que a propriedade obj.constructor realmente existe. Se a função não existe, então não há nenhum construtor, e não há necessidade de continuar. Se a função não existe, então uma expressão regular é usada para extrair o nome da função. A expressão regular no exemplo de código é mostrado em negrito e é reconhecida como uma expressão regular por causa das barras. Quando utilizar expressões regulares no contexto de uma cadeia, a função de jogo é chamado e retorna o resultado da partida. Se não houver resultados, em seguida, um identificador é encontrado que pode ser usado para fazer referência a propriedade prototype. Mas um buffer de texto e não um objeto se encontra. O buffer de texto tem de ser convertido em um objeto, utilizando a instrução eval. O buffer executado dinamicamente atribuirá o local declarado prototypeProperty fazer referência a propriedade prototype. Em seguida, utilizando um bloco de código, a propriedade eo identificador do objeto são passados para o chamador. Outro contexto é a serialização de uma instância do objeto que inclui apenas do estado e não funciona. Sem ainda ver o código, você provavelmente pode adivinhar o que o filtro faz. Os testes de filtro de código, se a propriedade a ser filtrada é uma função de objeto. Se a propriedade é um objeto de função, então a propriedade não deve ser filtrada. E, de fato, é assim que o código do filtro está escrito, como mostrado na listagem a seguir.

 Fonte: / website / root / scripts / Jaxson / commons.js Serializer.toSourceState = function (obj) (return ops.serialize (obj, (canProcessFilter: function (propriedade, obj, PropertyIdentifier) ( if (typeof (propriedade) == "function") (return false;) else (return true;))));)

O código em negrito mostra como testar o tipo de objeto usando o operador typeof. Outro contexto é a serialização de Estado para a notação JSON. Serialização JSON é como a serialização de um estado, exceto que a propriedade tem identificadores aspas em torno deles. O código de serialização é idêntico ao código de serialização do estado, exceto que o membro de dados quoteProperties é definida como true.

 Fonte: / website / root / scripts / Jaxson / commons.js Serializer.toSourceJSON = function (obj) (return ops.serialize (obj, ( quoteProperties: true,canProcessFilter: function (propriedade, obj, PropertyIdentifier) (if (typeof (propriedade) == "function") (return false;) else (return true;))));)

Depois de analisar os últimos três contextos de serialização, você provavelmente está pensando que o código é relativamente semelhante, mas os resultados são muito diferentes. Este é um exemplo de como os blocos de código pode ser usado para separar a iteração geral de um tratamento específico. Outro contexto de serialização que você vai usar que é semelhante ao toSource é serialização com uma referência. O contexto desta serialização é o seguinte. Você está criando um sistema onde um tipo serve como uma funcionalidade básica. Depois de ter o tipo instanciado, personalizações são executadas. Então você decide para serializar o objeto, mas você quer serializar apenas as personalizações, o motivo é que quando o objeto é recriado em outro computador ou programa, você quer uma funcionalidade de base diferente a ser utilizado. Assim, da mesma classe poderão operar com as funcionalidades de base diferentes. A solução é não serializar as propriedades do protótipo e gerar um buffer que instancia do tipo.

Nota Eu não explicar a execução do contexto de outros tipos de serialização porque eles não mostram quaisquer novas técnicas. Eu cobrem apenas como usar GetPrototypeObject em um contexto diferente e filtro de código mais complicado. Se você estiver interessado em saber mais, dê uma olhada no código de teste no ficheiro / website / ROOT / artigos ajax / javascript / tosource.html, e em particular o jaxson_tosource_oo método de ensaio. Serialização em JavaScript parece ser uma coisa simples , eo método toSource parece extremamente útil. No entanto, como discutido neste artigo, toSource está incompleto. Quando você escrever um código JavaScript para serializar, manter os seguintes pontos em mente:

• Serialização em JavaScript meios para gerar um buffer que é formatado no formato JavaScript Object.

• Neste artigo, nós não olhar para a forma de re-criar o objeto serializado. Isso porque, para fazê-lo apenas requer passar a reserva para a instrução eval e atribuindo os resultados de

eval para uma variável.

• Serialização tem muitos contextos diferentes. O ops.serialize função implementa uma serialização muito geral que precisa ser especializado.

• Quando a serialização, não há informações de tipo. Para ter informações sobre o tipo, é preciso extraí-lo e armazená-lo em algum lugar. Lembre-se que o JavaScript é um protótipo baseado em linguagem de programação e tipos de JavaScript são diferentes em termos de conceito, quando comparado aos tipos de linguagens como C # e Java.

• técnicas de serialização Este artigo mostra como definir um algoritmo que utiliza blocos de código para separar um bloco de código geral iteração de um bloco específico âmbito do código.

um artigo submetido por Sonja Lande


Isenção de responsabilidade:O nosso site não se responsabiliza pelo conteúdo deste artigo. Webarticles é uma fonte de informação livre.
Importante: Este artigo "Turning toSource em uma solução de serialização Completo" foi traduzida por um software automático. Nós sentimos muito por quaisquer erros de ortografia que pode ter ocorrido. Obrigado pela sua compreensão.


Online: 303 users browsing the articles directory