Puis-je construire un objet JavaScript sans utiliser le mot clé new?
Voici ce que j'aimerais faire:
function a() {
//...
}
function b() {
// Some magic, return a new object.
}
var c = b();
c instanceof b //-> true
c instanceof a //-> true
b instanceof a //-> true
Est-il possible? Je peux faire b
être une instance de a
facilement en connectant a
dans sa chaîne de prototype, mais puis-je faire new b()
, qui est ce que j'essaie d'éviter. Est ce que je veux possible?
Mise à jour: je pense qu'il pourrait être possible avec l'utilisation judicieuse de b.__proto__ = a.prototype
. Je vais faire des essais plus après le travail.
Mise à jour 2: ci-Dessous est ce qui semble être le plus proche que vous pouvez obtenir, ce qui est assez bon pour moi. Merci à tous pour les réponses intéressantes.
function a() {
//...
}
function b() {
if (!(this instanceof arguments.callee)) {
return new arguments.callee();
}
}
b.__proto__ = a.prototype
var c = b();
c instanceof b //-> true
c instanceof a //-> false
b instanceof a //-> true
Mise à jour 3: j'ai trouvé exactement ce que je voulais dans une blog sur la " puissance des constructeurs, une fois, j'ai ajouté l'essentiel b.__proto__ = a.prototype
ligne:
var object = (function() {
function F() {}
return function(o) {
F.prototype = o;
return new F();
};
})();
function a(proto) {
var p = object(proto || a.prototype);
return p;
}
function b(proto) {
var g = object(a(proto || b.prototype));
return g;
}
b.prototype = object(a.prototype);
b.__proto__ = a.prototype;
var c = b();
c instanceof b //-> true
c instanceof a //-> true
b instanceof a //-> true
a() instanceof a //-> true
Je suis entrain de créer un Javascript version de Scala le cas de classes: github.com/pr1001/caseclass.js
Ne voyant pas pourquoi, qui vous oblige à travailler autour de la
new
mot-clé. Et __proto__
ne va pas vous aider à croix-navigateur.C'est tout ce sucre syntaxique, rien de plus. Cependant, je pense que c'est un défi intéressant tout de même.
Double Possible de JavaScript: Comment faire pour créer une nouvelle instance d'une classe sans utiliser le mot clé new?
OriginalL'auteur pr1001 | 2009-12-11
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser ce modèle:
après quoi vous pouvez le faire:
En plus de cela (un peu vieux) réponse: vous pouvez utiliser un motif de module pour créer un objet:
Voici un jsFiddle pour certains
Date
les fonctionnalités que j'ai créé à l'aide de ce modèle.+1 c'est l'habitude d'un langage permettant d'autoriser les constructeurs à travailler sans
new
.Commentaire n ° 1: mais...mais...Mais...il utilise toujours
new
. Je ne vois pas le point ici, c'est juste une méthode de fabrique que aussi permet à l'utilisateur d'utilisernew
si ils le veulent. Qui mène juste à certains membres de l'équipe à l'aide denew
et d'autres pas; un entretien cauchemar. Le soutien de l'une ou de l'autre (par exemple, en incluant le code de débogage, vous retirer pour la production, qui lève une exception si l'auteur n'a pas -- ou -- utilisationnew
d'appeler le constructeur), mais pas les deux.Commentaire #2: Si vous souhaitez utiliser ce modèle, assurez-vous d'utiliser une fonction nommée (comme dans votre exemple) et d'utiliser le nom de la fonction, pas
arguments.callee
-- par exemple:if (!(this instanceof SomeConstructor))
. À l'aide dearguments.callee
va ralentir votre fonctions de façon spectaculaire (2-10x, selon le moteur JavaScript), et lève une exception en JavaScript nouveau "stricte" de mode.Désolé, T. J., si je n'ai pas été clair, mais j'ai été à la recherche pour le code où le de l'utilisateur final, pas la bibliothèque créateur, évité à l'aide de
new
.OriginalL'auteur KooiInc
Quel est le problème avec l'aide de la
new
mot-clé?En tout cas, il semble que la meilleure chose à faire est de lire sur Javascript héritage:
http://javascript.crockford.com/inheritance.html
Par tous les moyens, lire Crockford. Il est informé et d'éducation. Mais ne lisez pas Crockford comme parole d'évangile, pas moins parce que certains de ses précédents articles (au moins!) promouvoir extrêmement inefficace pratiques de programmation. Et je ne suis pas tout de suite à voir comment Crockford articles sur la simulation classique de l'héritage en JavaScript (aujourd'hui considérée par lui comme une "erreur") se rapportent à la question pragmatique posté par les OP.
stackoverflow.com/questions/377716/...
OriginalL'auteur Matt Ball
Quelqu'un a posté un article par douglas crockford, dans cette question, et il explique exactement ce que votre demande.
OO Javascript constructeur de modèle: le modèle néo-classique vs prototypes
new
(etthis
). Un peu extrême, mais il montre la puissance de la langue.instanceof ne renvoie pas les résultats souhaités dans la question.
OriginalL'auteur Zoidberg
La réponse simple à votre question est: non.
Il pourrait vous aider à identifier pourquoi vous voulez éviter
new
. Peut-être les motifs évoqués par l'une des autres réponses aideront. Cependant, aucun d'entre eux suite à lainstanceof
retourner true dans vos tests.La nouvelle opération est essentiellement:-
Cependant il y a la différence que la construction de
fn
est attaché à l'objet en utilisant certaines propriétés interne (oui, vous pouvez l'obtenir avecconstructor
mais la définition qu'il n'a pas le même effet). La seule façon d'obtenirinstanceof
à fonctionner comme prévu est d'utiliser lenew
mot-clé.OriginalL'auteur AnthonyWJones
Vous ne pouvez pas éviter
new
dans le cas général (sans aller à l'extrême, comme par le Crockford article Zoidberg indirectement liée à l') si vous voulez d'héritage et deinstanceof
de travail, mais ensuite (encore une fois), pourquoi voulez-vous ou devez?La seule raison pour laquelle je peux penser à l'endroit où vous souhaitez les éviter, il est si vous essayez de passer une fonction constructeur à un autre morceau de code qui ne sait pas que c'est un constructeur. Dans ce cas, il suffit de l'envelopper dans une usine de la fonction:
OriginalL'auteur T.J. Crowder
Vous pouvez créer des instances sans que le nouvel opérateur (ici, est un excellent article écrit par Douglas Crockford http://yuiblog.com/blog/2006/11/13/javascript-we-hardly-new-ya/). Mais il ne sera pas vous aider avec le "instanceof" histoire.
new
à utiliser, il est à propos de lieux spécifiques, vous pouvez l'éviter, comme avecObject
(utiliser{}
au lieu de cela),Array
(utiliser[]
à la place), et surtoutFunction
.La question était de savoir si c'est possible. L'article explique que OUI c'est possible, et il couvre également certains aspects pourquoi il peut être utile.
Non, il n'est pas. Il parle de ne pas utiliser
new
de façon inappropriée (commenew function() { ... }
), pas à propos en évitant l'utilisation de l'informatique en général. L'article ne parle pas de l'héritage à tous, en fait.Crowder: Mon erreur, vous n'avez pas remarqué l'idée derrière c exemple 🙂
OriginalL'auteur nemisj
Oui, vous pouvez le faire.
Est quelque chose de mal avec cette méthode?
OriginalL'auteur
La seule façon d'obtenir instanceof de travail est d'utiliser le mot clé new. instanceof exploits ____proto____ ce qui est établi par nouveau.
Malheureusement, je comprends proto est en lecture seule.
Bien sûr, proto est "trait de soulignement trait de soulignement proto soulignent le caractère de soulignement."
Yep, stupide mise en forme. Dans Rhino et le Chrome débogueur,
__proto__
ne semble pas être en lecture seule.C'est bon à savoir; j'ai lu quelque part qu' ____proto____ est obsolète. Pourrait être difficile de tact de poursuivre étant donné les différentes appraoches prises par les différents navigateurs.
OriginalL'auteur Upperstage
Des objets JavaScript peut être créé sans l'aide du mot clé new.
Par exemple la fonction suivante retourne un objet sans l'aide de mots clés,
instanceof
ne fonctionne pas comme l'OP veut en faire.OriginalL'auteur awin
Dans un javascript bookmarklet, vous pouvez utiliser la fonction eval(ne pas encoder("...")) pour créer un objet sans opérateur "new":
OriginalL'auteur diyism
En utilisant
Object.create
et le classiqueFunction.prototype
. La configuration de la chaîne de prototype correctement, vous préserver le bon fonctionnement de lainstanceof
mot, sans aucune utilisation de lanew
mot-clé.OriginalL'auteur rich remer