125 votes

Héritage JavaScript: Object.create vs new

Double Possible:
Quelle est la raison d'utiliser le "nouveau" mot-clé ici?

En JavaScript quelle est la différence entre ces deux exemples:

Préalable:

function SomeBaseClass(){
}

SomeBaseClass.prototype = {
    doThis : function(){
    },

    doThat : function(){
    }
}

Exemple d'héritage à l'aide d'Un Objet.créer:

function MyClass(){
}

MyClass.prototype = Object.create(SomeBaseClass.prototype);

Exemple d'héritage de B à l'aide du mot clé new

function MyClass(){
}

MyClass.prototype = new SomeBaseClass();

Ces deux exemples semblent faire la même chose. Quand vous avez choisi l'un sur l'autre?

Une question supplémentaire: Envisager de code dans le lien ci-dessous (ligne 15), où une référence à la fonction propre du constructeur est stocké dans le prototype. Pourquoi est-ce utile?

https://github.com/mrdoob/three.js/blob/master/src/loaders/ImageLoader.js

Extrait (si vous ne voulez pas à ouvrir le lien):

THREE.ImageLoader.prototype = {

    constructor: THREE.ImageLoader
}

115voto

WereWolf - The Alpha Points 49671

Dans votre question, vous avez mentionné qu' Both examples seem to do the same thing, Il n'est pas vrai du tout, parce que

Votre premier exemple

function SomeBaseClass(){...}
SomeBaseClass.prototype = {
    doThis : function(){...},
    doThat : function(){...}
}
function MyClass(){...}
MyClass.prototype = Object.create(SomeBaseClass.prototype);

Dans cet exemple, vous êtes juste d'hériter SomeBaseClass' prototype mais que faire si vous avez une propriété dans votre SomeBaseClass comme

function SomeBaseClass(){ 
    this.publicProperty='SomeValue'; 
}

et si vous l'utilisez comme une

var obj=new MyClass();
console.log(obj.publicProperty); // undefined
​console.log(obj);​

L' obj objet n'aurez pas publicProperty de la propriété, comme dans cet exemple.

Votre deuxième exemple

MyClass.prototype = new SomeBaseClass();

C'est l'exécution de l' constructor fonction, faire une instance d' SomeBaseClass et hériter de l'ensemble de l' SomeBaseClass objet. Donc, si vous utilisez

    var obj=new MyClass();
    console.log(obj.publicProperty); // SomeValue
    console.log(obj);​

Dans ce cas, il est publicProperty de la propriété est également disponible à l' obj objet, comme dans cet exemple.

Depuis l' Object.create n'est pas disponible dans certains navigateurs plus anciens, dans ce cas, vous pouvez utiliser

if(!Object.create)
{
    Object.create=function(o){
        function F(){}
        F.prototype=o;
        return new F();
    }
}

Au-dessus de code ajoute que l' Object.create fonction si elle n'est pas disponible, de sorte que vous pouvez utiliser Object.create fonction et je pense que le code ci-dessus décrit ce qu' Object.create la réalité. Espère que ça vous aidera, d'une certaine façon.

40voto

Bergi Points 104242

Ces deux exemples semblent faire la même chose.

C'est vrai dans votre cas.

Quand vous avez choisi l'un sur l'autre?

Lors de l' SomeBaseClass a un corps de la fonction, ce serait exécuté avec l' new mot-clé. Ce n'est généralement pas prévu - vous ne voulez configurer la chaîne de prototype. Dans certains cas, il pourrait même causer de sérieux problèmes car vous instanciez un objet, dont la portée des variables sont partagées par tous MyClass d'instances qu'ils héritent de la même privilégié des méthodes. D'autres effets secondaires sont possibles et imaginables.

Donc, vous devriez généralement préfèrent Object.create. Pourtant, il n'est pas pris en charge dans certains anciens navigateurs, qui est la raison pour laquelle vous voyez l' new-approche trop souvent qu'il n'a souvent pas (évident) de nuire. Aussi jeter un oeil à cette réponse.

8voto

jAndy Points 93076

La différence devient évidente si vous utilisez Object.create() car il est destiné. En fait, il n'entièrement repaire de l' prototype word à partir de votre code, il va faire le travail sous le capot. À l'aide de Object.create(), nous pouvons aller comme

var base =  {
    doThis : function(){
    },

    doThat : function(){
    }
};

Et puis on peut étendre/inherit d'autres objets à partir de ce

var myObject = Object.create( base );
// myObject will now link to "base" via the prototype chain internally

Donc, c'est un autre concept, plus "orienté objet" façon de inherting. Il n'y a pas de "fonction constructeur" hors de la boîte, en utilisant Object.create() par exemple. Mais bien sûr, vous pourriez créer et appeler une auto définis en fonction de constructeur au sein de ces objets.

Un argument pour l'utilisation de Object.create() , c'est qu'il peut regarder de plus naturel pour mélanger/*hériter* à partir d'autres objets, que l'utilisation de Javascript par défaut.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X