¡Es posible ocultar el prototipo de Javascript Object!¿Cuál es el misterio detrás de esto?

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

Pregunta

Estoy usando Openui5.Hay una función de constructor para el botón de control UI, no se puede ver las propiedades del prototipo del botón, pero lo mismo cuando se ejecuta en la consola del navegador, ¡aparece!

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

El mismo código cuando se ejecuta el navegador ejecutado en la consola, funciona!

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

¿Fue útil?

Solución

Después de ejecutar el código, encuentro que la creación de la primera instancia de SAP.M.BUTTON CAUSA Script para cambiar el prototipo de SAP.M.BUTTON. Es válido en JavaScript pero no muy inteligente si me preguntas.

Una primera creación provoca una solicitud síncrona (no, no también) para buscar la biblioteca-parámetros.json.

Si ejecuta el código la segunda vez, tendrá prototype.move porque creando una instancia de botón no cambiará el botón.Prototipo.

El capital M en movimiento sugeriría una función de constructor para que le aconsejaría cambiarlo a minúsculas.

Dado que la recuperación de los parámetros es sincrónica, puede crear la primera instancia y luego configurar el prototipo:

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

Mi conjetura es que esto se hace a los controles de carga perezosos, si nunca se crea un botón, los archivos de configuración de JSON nunca se cargan para estos controles no utilizados. Sin embargo, tiene un par de inconvenientes.

  1. Tienes que crear una instancia primero antes de poder configurar el prototipo.
  2. Los archivos de configuración se cargan sincrónicamente, por lo que cuando la creación de primera instancia de muchos controles con una conexión lenta hará que la aplicación no responde.
  3. Una mejor manera sería que una función de fábrica devolverá una promesa para que cree el control de la misma manera cada vez que se pueden obtener los archivos de configuración de forma asíncrona.

    [actualizar]

    Mirando la configuración Parece que está configurada para toda la biblioteca GUI, por lo que no puedo ver ninguna razón por la que esto se carga solo después de crear una primera instancia. Una biblioteca que cambia sus definiciones de objetos al crear instancias no es muy fácil de extender porque es impredecible. Si solo cambia el prototipo en la primera creación, entonces debería estar bien, pero parece que los fabricantes de la biblioteca no querían que las personas lo extendieran o no harían la definición del objeto impredecible. Si hay una documentación API disponible, tal vez intente verificar eso.

    [actualizar]

    Parece que la forma "correcta" de extender los controles es usar extender .

Otros consejos

@hmr es correcto la forma correcta de extender un control es mediante la función de extensión proporcionada por los objetos administrados UI5,Consulte http://jsbin.com/linob/1/edit

En el ejemplo a continuación cuando se depure según lo mencionado por otros, notará que el control se carga perezoso cuando sea necesario, cualquier cambio que realice antes se pierde cuando se cargan

    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();

No está ocultando el prototipo per se. Si una función de constructor sale normalmente, entonces obtiene el prototipo de esa función. Pero si una función de constructor realmente devuelve algún otro objeto, entonces obtiene el prototipo de ese otro objeto, por lo que no es válido asumir que solo porque agregó al botón prototipo que cuando llame al botón nuevo () que verá su método en lo que sea regreses. Estoy seguro de que si desactiva ese código, encontrará que el constructor que está llamando tiene un "retorno de nuevo tantotherinstanceofbutton ()" o similar al final de ello.

Editar: OK Es un poco difícil ver lo que realmente está pasando en ese código SAP, pero parece que tienen código que sobrescribe los prototipos de controles para agregar características, como: sap.ui.core.enabledpropagator , y esas cosas no se ejecutan hasta que realmente instanete un botón. Entonces, si cambia su código para instanciar el botón en la página, agregue a su prototipo, luego construya y llame al método, funciona bien. Me gusta así:

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

Supongo que mi respuesta es, cuando lo ejecuta desde la consola, ha terminado de pasar con ese prototipo, mientras que en su prueba estaba agregando al prototipo, luego construyendo el botón por primera vez (lo que cambia el prototipo nuevamente) Luego tratando de llamar a su antiguo, que ya no está allí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top