È possibile nascondere il prototipo dell'oggetto di JavaScript!Qual è il mistero dietro questo?

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

Domanda

Sto usando OpenUI5.C'è una funzione costruttore per il pulsante di controllo dell'interfaccia utente, impossibile vedere le proprietà del prototipo del pulsante, ma la stessa cosa quando eseguita nella console del browser, viene visualizzata!

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

lo stesso codice quando eseguito il browser in console, funziona!

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

È stato utile?

Soluzione

Dopo aver eseguito il codice trovo che la creazione della prima istanza di sap.m.button causa lo script di modificare il prototipo di sap.m.button. È valido in JavaScript ma non molto intelligente se mi chiedi.

Una prima creazione causa una richiesta sincrona (no no pure) di recuperare la libreria-parametri.json.

Se si esegue il codice la seconda volta che avrà prototipo.Move perché la creazione di un'istanza del pulsante non cambierà il pulsante. Prototipo.

La capitale m in movimento suggerirebbe una funzione di costruttore in modo da consigliare di cambiarlo in minuscolo.

Poiché il recupero dei parametri è sincrono è possibile creare la prima istanza e quindi impostare il 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
.

La mia ipotesi è che questo è fatto ai controlli di caricamento pigro, se un pulsante non viene mai creato, i file di configurazione JSON non vengono mai caricati per questi controlli inutilizzati. Ha un paio di inconvenienti però.

    .
  1. È necessario creare un'istanza prima di poter impostare il prototipo.
  2. I file di configurazione vengono caricati in modo sincrono in modo tale da creare una prima istanza di molti controlli con una connessione lenta farà che l'app non rispondesse.
  3. Un modo migliore sarebbe per una funzione di fabbrica per restituire una promessa in modo da creare il controllo allo stesso modo ogni volta e i file di configurazione possono essere recuperati asincroni.

    [Aggiornamento]

    Guardando la configurazione Sembra essere config per l'intera libreria GUI, quindi non riesco a vedere nessun motivo per cui questo è caricato solo dopo aver creato una prima istanza. Una biblioteca che cambia le sue definizioni dell'oggetto quando la creazione di istanze non è molto facile da estendere perché è imprevedibile. Se cambia solo il prototipo sulla prima creazione, dovrebbe andare bene, ma sembra che i produttori della biblioteca non volevano che le persone lo prolungano o non farebbero la definizione dell'oggetto imprevedibile. Se c'è una documentazione API disponibile, quindi cercare di verificarlo.

    [Aggiornamento]

    Sembra che il modo "corretto" per estendere i controlli sia quello di usare Estendi .

Altri suggerimenti

@HMR è giusto Il modo corretto per estendere un controllo è utilizzando la funzione di estensione fornita dagli oggetti gestiti UI5,Vedi http://jsbin.com/linob/1/edit

Nell'esempio seguente quando il debug è stato menzionato da altri noterai che il controllo è Pigre caricato quando richiesto, eventuali modifiche apportate preventive vengono perse quando caricato

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

Non nasconde il prototipo di per sé. Se una funzione di costruttore si spegne normalmente quindi ottieni il prototipo di quella funzione. Ma, se una funzione di costruttore restituisca effettivamente un altro oggetto, quindi ottieni il prototipo di un altro oggetto, quindi non è valido per supporre che sia stato aggiunto al prototipo del pulsante quando si chiama nuovo pulsante () che vedrai il tuo metodo su qualsiasi cosa Torna. Sono sicuro che se si de-offusca quel codice che scoprirai che il costruttore che stai chiamando ha un "ritorno nuovo someotherinstanceofbutton () o simile alla fine di esso.

Modifica: Ok è un po 'difficile vedere cosa sta succedendo in quel codice SAP, ma sembra che abbiano il codice che sovrascrive i prototipi dei controlli per aggiungere funzionalità a loro, come ad esempio: sap.ui.core.evenbledProppagator , e quelle cose non vengono eseguite fino a quando non ti istanzia un pulsante. Quindi se si modifica il codice per istanziare il pulsante sulla pagina, quindi aggiungi al suo prototipo, quindi costruisci e chiama il metodo, funziona bene. Come così:

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

Quindi immagino che la mia risposta sia, quando lo esegui da console, è finito di fusione con quel prototipo, mentre nel test stavi aggiungendo al prototipo, quindi costruendo il pulsante per la prima volta (che cambia di nuovo il prototipo) Quindi cerca di chiamare il tuo vecchio, che non è più lì.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top