É possível OCULTAR o protótipo do objeto Javascript!Qual é o MISTÉRIO por trás disso?

StackOverflow https://stackoverflow.com//questions/23005462

Pergunta

Estou usando o openui5.Existe uma função construtora para o botão de controle da UI, não é possível ver as propriedades do protótipo do botão, mas a mesma coisa quando executada no console do navegador aparece!

 sap.m.Button.prototype.Move = function(){
  console.log('Move');
} 
var oButton = new sap.m.Button({text:"Hello"});
oButton.Move(); // throws undefined function! 

O mesmo código quando executado no navegador no console, funciona!

jsbin --> http://jsbin.com/tepum/1/edit

Foi útil?

Solução

Depois de executar o código, descobri que a criação da primeira instância do sap.m.Button faz com que o script altere o protótipo do sap.m.Button.É válido em JavaScript, mas não é muito inteligente se você me perguntar.

Uma primeira criação causa uma solicitação síncrona (não, não também) para buscar biblioteca-parameters.json.

Se você executar o código pela segunda vez, ele terá protótipo.move porque criar uma instância de Button não alterará Button.prototype.

O M maiúsculo em Move sugeriria uma função construtora, então aconselho alterá-la para minúsculas.

Como a busca dos parâmetros é síncrona, você pode criar a primeira instância e depois definir o protótipo:

console.log("First Button creation changes Button.prototype");
var oButton = new sap.m.Button({text:"Hello"});
sap.m.Button.prototype.move = function(){
  console.log('Move');
} 
oButton.placeAt('content');
oButton.move(); // logs Move

Meu palpite é que isso é feito para controles de carregamento lento. Se um botão nunca for criado, os arquivos de configuração json nunca serão carregados para esses controles não utilizados.No entanto, tem algumas desvantagens.

  1. Você deve criar uma instância primeiro antes de definir o protótipo.
  2. Os arquivos de configuração são carregados de forma síncrona, portanto, ao criar a primeira instância de muitos controles com uma conexão lenta, o aplicativo não responderia.

Uma maneira melhor seria uma função de fábrica retornar uma promessa para que você criasse o controle da mesma maneira todas as vezes e os arquivos de configuração pudessem ser buscados de forma assíncrona.

[atualizar]

Olhando para a configuração, parece ser uma configuração para toda a biblioteca GUI, então não consigo ver nenhuma razão para que isso seja carregado somente após a criação de uma primeira instância.Uma biblioteca que altera suas definições de objeto ao criar instâncias não é muito fácil de estender porque é imprevisível.Se ele mudar apenas o protótipo na primeira criação, tudo bem, mas parece que os criadores da biblioteca não queriam que as pessoas a estendessem ou não tornariam a definição do objeto imprevisível.Se houver uma documentação da API disponível, talvez tente verificar isso.

[atualizar]

Parece que a maneira "correta" de estender os controles é usar ampliar.

Outras dicas

@HMR está certo, a maneira correta de estender um controle é usando a função de extensão fornecida pelos objetos gerenciados UI5, consulte http://jsbin.com/linob/1/edit

no exemplo abaixo, ao depurar conforme orientado por outros, você notará que o controle é carregado lentamente quando necessário, quaisquer alterações feitas anteriormente serão perdidas quando carregadas

    jQuery.sap.declare("my.Button");
    jQuery.sap.require("sap.m.Button");
    sap.m.Button.extend("my.Button", {
        renderer: {} 
    });

    my.Button.prototype.Move = function() {
        console.log('Move');
    };

    var oButton = new my.Button({
        text: "Hello"
    });
    oButton.placeAt('content');
    oButton.Move();

Não está escondendo o protótipo em si.Se uma função construtora sair normalmente, você obterá o protótipo dessa função.Mas, se uma função construtora realmente retorna algum outro objeto, então você obtém o protótipo desse outro objeto, então não é válido assumir que só porque você adicionou ao protótipo Button que quando você chamar new Button() você verá seu método em qualquer coisa você volta.Tenho certeza de que, se você desofuscar esse código, descobrirá que o construtor que está chamando tem um "return new SomeOtherInstanceOfButton ()" ou similar no final dele.

Editar:Ok, é um pouco difícil ver o que realmente está acontecendo naquele código SAP, mas parece que eles têm um código que substitui os protótipos de controles para adicionar recursos a eles, como:sap.ui.core.EnabledPropagator, e essas coisas não são executadas até que você realmente instancie um botão.Portanto, se você alterar seu código para instanciar o botão na página, adicioná-lo ao protótipo, construir e chamar o método, ele funcionará bem.Igual a:

http://jsbin.com/benajuko/2/edit

Então, acho que minha resposta é: quando você o executa no console, ele termina de mexer no protótipo, enquanto no seu teste você estava adicionando ao protótipo, depois construindo o botão pela primeira vez (o que muda o protótipo novamente) e depois tentando ligue para o seu antigo, que não está mais lá.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top