En JavaScript, quelle est la différence entre ces deux exemples:
Prérequis:
function SomeBaseClass(){
}
SomeBaseClass.prototype = {
doThis : function(){
},
doThat : function(){
}
}
Exemple d'héritage A utilisant Object.create:
function MyClass(){
}
MyClass.prototype = Object.create(SomeBaseClass.prototype);
Exemple d'héritage B utilisant le nouveau mot-clé
function MyClass(){
}
MyClass.prototype = new SomeBaseClass();
Les deux exemples semblent faire la même chose. Quand choisiriez-vous l'un plutôt que l'autre?
Une question supplémentaire: considérez le code dans le lien ci-dessous (ligne 15), où une référence au propre constructeur de la fonction est stockée dans le prototype. Pourquoi est-ce utile?
https://github.com/mrdoob/three.js/blob/master/src/loaders/ImageLoader.js
Extrait (si vous ne souhaitez pas ouvrir le lien):
THREE.ImageLoader.prototype = {
constructor: THREE.ImageLoader
}
javascript
inheritance
object-create
ChrisRich
la source
la source
Object.create
. Ceci est une erreur et devrait être rouvert.Réponses:
Dans votre question, vous avez mentionné que
Both examples seem to do the same thing
ce n'est pas vrai du tout, carVotre premier exemple
Dans cet exemple, vous héritez juste
SomeBaseClass' prototype
mais que faire si vous avez une propriété dans votreSomeBaseClass
genreet si vous l'utilisez comme
L'
obj
objet n'aura pas depublicProperty
propriété comme dans cet exemple .Votre deuxième exemple
Il exécute la
constructor
fonction, crée une instanceSomeBaseClass
et hérite de tout l'SomeBaseClass
objet. Donc, si vous utilisezDans ce cas, sa
publicProperty
propriété est également disponible pour l'obj
objet comme dans cet exemple .Comme le
Object.create
n'est pas disponible dans certains anciens navigateurs, dans ce cas, vous pouvez utiliserLe code ci-dessus ajoute simplement une
Object.create
fonction s'il n'est pas disponible afin que vous puissiez utiliser laObject.create
fonction et je pense que le code ci-dessus décrit ce queObject.create
fait réellement. J'espère que cela aidera d'une certaine manière.la source
SomeBaseClass
.C'est vrai dans votre cas.
Quand
SomeBaseClass
a un corps de fonction, cela serait exécuté avec lenew
mot - clé. Ce n'est généralement pas prévu - vous souhaitez uniquement configurer la chaîne de prototypes. Dans certains cas, cela peut même causer de graves problèmes car vous instanciez en fait un objet, dont les variables de portée privée sont partagées par toutes lesMyClass
instances car elles héritent des mêmes méthodes privilégiées. D'autres effets secondaires sont imaginables.Donc, vous devriez généralement préférer
Object.create
. Pourtant, il n'est pas pris en charge dans certains navigateurs hérités; c'est la raison pour laquelle vous voyez l'new
approche beaucoup trop fréquente car elle ne fait souvent aucun mal (évident). Jetez également un œil à cette réponse .la source
La différence devient évidente si vous utilisez
Object.create()
comme prévu. En fait, il cache entièrement leprototype
mot de votre code, il fera le travail sous le capot. En utilisantObject.create()
, nous pouvons aller commeEt puis nous pouvons étendre / hériter d'autres objets de ce
C'est donc un autre concept, une manière d'hériter plus "orientée objet". Il n'y a pas de "fonction constructeur" prête à l'emploi en utilisant
Object.create()
par exemple. Mais bien sûr, vous pouvez simplement créer et appeler une fonction de constructeur auto-définie dans ces objets.Un argument pour utiliser
Object.create()
est qu'il peut sembler plus naturel de mélanger / * hériter * d'autres objets que d'utiliser la méthode par défaut de Javascripts .la source
Object.create
ne peut pas vraiment remplacer l'approche classique avecnew
quand une fonction de constructeur est nécessaireObject.create
n'appelle pas une fonction qui serait nécessaire pour créer des fermetures. Bien sûr, avecObject.create
vous pouvez mettreinit
méthode sur vos objets et appel qui immédiatement et peut - être même retournethis
pour que vous obtenez une syntaxe concise - mais attendez, c'est un constructeur alors.new
utilise le "lien d'objet", donc il n'y a pas beaucoup de différence. En fait, il n'y a que deux choses:.constructor
est appelée.init
, et cette fonction n'a pas de.prototype
propriété pointant vers votre objet prototype. Le reste n'est que de la syntaxe - et je préfèrenew X
plusObject.create(x).init()
.Je ne suis pas un expert en script java mais voici un exemple simple pour comprendre la différence entre "Object.create" et "new" ..
étape 1: créez la fonction parent avec quelques propriétés et actions.
étape 2: créez une fonction enfant (PersonSalary) qui s'étend au-dessus de la fonction Person à l'aide du nouveau mot clé.
étape 3: créez une deuxième fonction enfant (PersonLeaves) qui s'étend au-dessus de la fonction Person en utilisant le mot-clé Object.create .
// Vérifiez maintenant les deux prototypes de fonctions enfants.
ces deux fonctions enfants seront liées au prototype Person (fonction parent) et pourront accéder à ses méthodes, mais si vous créez une fonction enfant en utilisant new, elle renverra un tout nouvel objet avec toutes les propriétés parent dont nous n'avons pas besoin et aussi lorsque vous en créez objet ou fonction utilisant "New" cette fonction parent est exécutée ce que nous ne voulons pas être.
Voici les plats à emporter
la source