Est-il possible de masquer le prototype de l'objet JavaScript!Quel est le mystère derrière ça?

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

Question

J'utilise openui5.Il existe une fonction de constructeur pour le bouton de commande d'interface utilisateur, impossible de voir les propriétés de prototype du bouton, mais la même chose lorsqu'elle est exécutée dans la console de navigateur, apparaît!

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

le même code lorsqu'un navigateur exécuté dans la console, cela fonctionne!

JSBIN -> http://jsbin.com/tepum/1/edith.com/a>

Était-ce utile?

La solution

Après avoir exécuté le code, je constate que la création de la première instance de sap.m.button provoque le changement de script de modifier le prototype de sap.m.button. C'est valable en JavaScript mais pas très intelligent si vous me demandez.

Une première création provoque une demande synchrone (non non aussi) de récupérer des paramètres de bibliothèque.json.

Si vous exécutez le code la deuxième fois qu'il aura du prototype.Move, car la création d'une instance de bouton ne changera pas le bouton.Prototype.

La capitale M en mouvement suggérerait une fonction de constructeur afin que je conseille de le modifier en minuscule.

Étant donné que la récupération des paramètres est synchrone, vous pouvez créer la première instance, puis définir le prototype:

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

Je suppose que cela se fait sur des contrôles de charge paresseux, si un bouton n'est jamais créé, les fichiers de configuration JSON ne sont jamais chargés pour ces contrôles inutilisés. Il a quelques inconvénients cependant.

  1. Vous devez d'abord créer une instance avant de pouvoir définir le prototype.
  2. Les fichiers de configuration sont chargés de manière synchrone, alors lors de la création de la première instance de nombreuses commandes avec une connexion lente entraîneraient l'inscription de l'application.
  3. Un meilleur moyen serait pour une fonction d'usine de renvoyer une promesse afin de créer la commande de la même manière à chaque fois et que les fichiers de configuration peuvent être récupérés de manière asynchrone.

    [mise à jour]

    En regardant la configuration, il semble être de configuration pour toute la bibliothèque de l'interface graphique afin que je ne puisse voir aucune raison pour laquelle cela est chargé uniquement après la création d'une première instance. Une bibliothèque qui change ses définitions d'objet lors de la création d'instances n'est pas très facile à prolonger, car elle est imprévisible. Si cela ne change que le prototype sur la première création, cela devrait aller bien, mais on dirait que les fabricants de la bibliothèque ne souhaitaient pas que les gens l'étendent ou ne rendraient pas la définition de l'objet imprévisible. S'il y a une documentation API disponible, essayez peut-être de vérifier cela.

    [mise à jour]

    Il semble que le moyen "correct" d'étendre les contrôles consiste à utiliser étendre .

Autres conseils

@hmr est correct le moyen correct d'étendre une commande consiste à utiliser la fonction d'expansion fournie par des objets gérés UI5,Voir http://jsbin.com/linob/1/edit

Dans l'exemple ci-dessous lors du débogage comme mentonné par d'autres personnes, vous remarquerez que le contrôle est chargé paresseux lorsque nécessaire, les modifications que vous faites préalables sont perdues lorsqu'elles sont chargées

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

Cela ne cache pas le prototype en soi. Si une fonction de constructeur sort normalement, vous obtenez le prototype de cette fonction. Mais, si une fonction de constructeur renvoie en réalité un autre objet, vous obtenez le prototype d'autre objet, il n'est donc pas valide de supposer que, simplement parce que vous avez ajouté au prototype du bouton que lorsque vous appelez Nouveau bouton () que vous verrez votre méthode sur tout vous obtenez en retour. Je suis sûr que si vous désactivez ce code, vous constaterez que le constructeur que vous appelez a un «retour neuf quelqueherInstanceObutton ()» ou similaire à la fin de celui-ci.

EDIT: OK C'est un peu difficile de voir ce qui se passe vraiment dans ce code SAP, mais il semble qu'ils ont un code qui écrase les prototypes des contrôles pour y ajouter des fonctions, telles que: sap.ui.core.enabledpropagator et ces choses ne sont pas courues avant d'instancier un bouton. Donc, si vous modifiez votre code pour instancier le bouton de la page, ajoutez-le à son prototype, puis construisez et appelez la méthode, cela fonctionne bien. Comme:

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

Donc, je suppose que ma réponse est, lorsque vous l'exécutez à partir de la console, il est fini, il est fini avec ce prototype, alors que dans votre test, vous avez ajouté au prototype, puis construisez le bouton pour la première fois (ce qui modifie à nouveau le prototype). Ensuite, essayant d'appeler votre ancien, ce qui n'est plus là.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top