7
votes

Version d'objet JavaScript dans la console.log

Je veux savoir d'où se trouve la console.log obtenir le nom de la fonction de construction lors de l'impression d'un objet. En outre, cela affecte-t-il réellement quelque chose de code sage? XXX PRE>

La sortie de la console.log (en chrome) est la suivante: F {test: "ok"}} p>

où la console.log obtenir le f code> dans f {test ... code>? P>

Si je change f.constructor code>, f.pototype code> et f.constructor code> à quelque chose de hasard, il imprime toujours l'original F code>: p> xxx pré>

La sortie est toujours la même - f {test: "ok"} code> p> p>

Cette information est-elle simplement conservée en privé par le navigateur, ma question est-elle affectant le code JavaScript de quelque manière que ce soit? C'est-à-dire que cela rampera-t-il pendant la comparaison ou l'héritage, après avoir remplacé le prototype de constructeur code> constructeur code> constructeur code> p>

Mise à jour forte > p>

L'objectif initial était de faire ce qui suit. p>

function Person ( _name ) {
    this.name = _name;
}

function Construct( _constructor, _args, _context ) {
    function F () {
        var context = _context || this;
        return _constructor.apply( context, _args );
    }

    /* I want to have the constructed object by identified 
       as _constructor and not a F */
    F.prototype = _constructor.prototype;

    return new F();
}

function Make ( _who ) {
    if ( 'person' === _who ) {
        /* Remove the first argument, who, and pass along all the rest.
           Constructors cannot be called with .apply so I have to use 
           this technique. */
        return Construct( Person, Array.prototype.slice.call( arguments, 1 ) );
    }
}

var dev = Make( 'person', 'John Doe' );

console.log( dev ); // prints `F {name: "John Doe"}`


1 commentaires

J'ai ajouté une autre réponse qui cible le problème initial que vous avez eue, au lieu d'essayer de faire fonctionner votre solution.


5 Réponses :


3
votes

Changer F.Prototype remplace le contenu de F , pas le nom. L'ancien objet prototype existe toujours et une référence à celle-ci est stockée en interne dans chaque instance de l'ancien F . Vous CAM Vérifiez-le en appelant f. __Proto __ ' (obscuré) ou objet.geprototypeof (f) .

Notez que __ proto __ est une protestation d'accesseur (à l'intérieur d'une getter, pas une propriété réelle), il ne peut donc pas être changé.


7 commentaires

Notez les liens vers Object.SeProTotypeof dans les deux spécifications de __ proto __ et objet.geprotypeof . Cette fonction, tout en prise en charge par Mozilla, est considérée comme expérimentale - et son utilisation est également découragée. Raisons données dans la spécification.


Bien que OP a changé de prototype objet f.pototype = g; l'ignore pendant un moment. Permet de changer f.pototype.constructor = g; à la place. Maintenant, objet.geprototypeof (f) .Constructeur ou f .__ proto __. Constructeur est également g . Mais console.log (f) imprime toujours f . Donc, je ne sais pas comment cet article répond à la question.


@ YK1 Cela peut être dépendant du navigateur. Utilisation de la version actuelle de Firefox, la modification de __ proto __ change la sortie pour moi.


Pour moi, il est plus important que les f sont reconnus comme G. si c'est le cas, mais la console.log imprime comme f et c'est la seule mise en garde, je serai heureux.


L'exemple de Exemple de l'opérateur FOP compare les objets .pototype AFAIK. Donc, si vous les remplacez (en utilisant quelquef.pototype au lieu de f.pototype ), il devrait fonctionner. Pas sûr de cela cependant. Vous pouvez lire la documentation de tout ce que vous voulez faire avec le prototype très soigneusement.


@JoHANNESH.: Je vois, oui, après avoir changé f.pototype.constructor = g; Firebug Prints g mais chrome dev outil toujours imprimé F .


Donc, ma réponse n'est pas globale alors, mais seulement serviable pour Firebug / Firefox. Je ne savais pas qu'ils étaient différents - on continue à apprendre tous les jours;)



0
votes

Votre création d'une nouvelle instance de F, le navigateur imprime donc pour vous aider à garder une trace de votre journalisation. Même si vous modifiez le prototype, vous devrez-vous toujours créer un nouveau "F" afin d'obtenir l'objet.

function A () { something: 123 }
new A();
console.log result: A {}
new B();
console.log result: ReferenceError: B is not defined


2 commentaires

Cela ne répond pas vraiment à la question ... Le point est le suivant: pourquoi le navigateur sait-il quel type l'objet a, même si son constructeur a été remplacé et que le prototype a été modifié?


Ahh, mal compris la question alors. Ne fera pas de modifier car vous avez déjà une réponse que je ressens bien.



0
votes

objet.constructor.name est un autre moyen d'obtenir le nom d'un constructeur d'objet.


1 commentaires

pas si vous avez changé objet.constructor (qui est correct pour faire et fonctionne bien), tout comme l'OP :)



1
votes

Ce n'est pas difficile, car f est finalement une instance de F et l'ordre de la portée de la portée (ce prototype, ...) est évident: -)

Par exemple, vous pouvez exécuter ce code et vous pouvez Voir que dans ce cas, il imprimera g: xxx


6 commentaires

vous répondez aux prospects que de la conclusion que f.pototype = g; F.constructor = g; étaient inutiles ...


@Johanhanh. Oui Cause Vous créez une nouvelle instance de: var f = nouveau f (); Voir le f ?


La question était la suivante: comment le navigateur sait-il que si toutes les références à F ont été modifiées. (Bien sûr, la réponse est "ils n'ont pas", mais le but est le suivant: où est-ce la dernière instance?). Le vbrowser n'utilise pas le code SourceCode pour rechercher la création initiale de l'objet, le type peut en effet être déterminé au moment de l'exécution.


@ Rokoc.Buljan Différence entre ce code et le code OPS est: devlato change f.pototype également (ce qui change effectivement le type L'objet a), op non.


@Johannesh C'est un lieu commun que si vous attribuez à un var f Un objet - console tentera d'afficher le nom de la fonction de référence (+ objet). Sinon, quelle op s'attend à faire I.E: console.log (f.fail); ? Rien de cause retournera non défini


Tout vrai. Il faut toujours y avoir un moyen pour le navigateur d'obtenir cette information, ce qui est ce que l'OP voulait savoir.



0
votes

Puis-je suggérer une autre approche pour l'intention initiale? Il n'y a aucun problème à utiliser simplement une référence différente de l'objet prototype au lieu de l'original, vous pouvez donc faire xxx

ceci devrait créer le bon objet en premier lieu, pas besoin d'échanger tout prototypes.


1 commentaires

Le problème est que le constructeur recevra maintenant un tableau ['John Doe'] au lieu d'une chaîne 'John Doe'. Je sais que je peux expliquer cela à l'aide de chèques de typeOf, mais je veux que le constructeur de la personne utilise la même signature.