Herança JavaScript: Object.create vs new

Em JavaScript, qual é a diferença entre esses dois exemplos:

Pré-requisito:

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

Exemplo de inheritance A usando Object.create:

 function MyClass(){ } MyClass.prototype = Object.create(SomeBaseClass.prototype); 

Exemplo de inheritance B usando a nova palavra-chave

 function MyClass(){ } MyClass.prototype = new SomeBaseClass(); 

Ambos os exemplos parecem fazer a mesma coisa. Quando você escolheria um sobre o outro?

Uma pergunta adicional: Considere o código no link abaixo (linha 15), onde uma referência ao construtor da function é armazenada no protótipo. Por que isso é útil?

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

Trecho (se você não quiser abrir o link):

 THREE.ImageLoader.prototype = { constructor: THREE.ImageLoader } 

Na sua pergunta você mencionou que Both examples seem to do the same thing , não é verdade, porque

Seu primeiro exemplo

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

Neste exemplo, você está apenas herdando SomeBaseClass' prototype mas e se você tem uma propriedade em seu SomeBaseClass como

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

e se você usar como

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

O object obj não terá a propriedade publicProperty como neste exemplo .

Seu segundo exemplo

 MyClass.prototype = new SomeBaseClass(); 

Está executando a function constructor , fazendo uma instância de SomeBaseClass e herdando todo o object SomeBaseClass . Então, se você usar

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

Nesse caso, sua propriedade publicProperty também está disponível para o object obj como neste exemplo .

Como o Object.create não está disponível em alguns navegadores antigos, nesse caso você pode usar

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

O código acima apenas adiciona a function Object.create , se não estiver disponível, para que você possa usar a function Object.create e acho que o código acima descreve o que o Object.create realmente faz. Espero que ajude de alguma forma.

Ambos os exemplos parecem fazer a mesma coisa.

Isso é verdade no seu caso.

Quando você escolheria um sobre o outro?

Quando SomeBaseClass tem um corpo de function, isso seria executado com a new palavra-chave. Isso geralmente não é intencional – você só quer configurar a cadeia de protótipos. Em alguns casos, pode até causar sérios problemas porque você realmente instancia um object, cujas variables ​​de escopo privado são compartilhadas por todas as instâncias de MyClass medida que elas herdam os mesmos methods privilegiados. Outros efeitos colaterais são imagináveis.

Portanto, você geralmente deve preferir o Object.create . No entanto, não é suportado em alguns navegadores legados; que é a razão pela qual você vê a new abordagem muito frequente, pois freqüentemente não causa dano (óbvio). Também dê uma olhada nesta resposta .

A diferença se torna óbvia se você usar Object.create() conforme pretendido. Na verdade, oculta inteiramente a palavra prototype do seu código, ela fará o trabalho sob o capô. Usando Object.create() , podemos ir como

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

E então podemos estender / herdar outros objects deste

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

Então, esse é outro conceito, uma maneira mais “orientada a objects” de herdar. Não há “function de construtor” fora da checkbox usando Object.create() por exemplo. Mas é claro que você poderia simplesmente criar e chamar uma function de construtor auto-definida dentro desses objects.

Um argumento para usar Object.create() é que pode parecer mais natural misturar / * herdar * de outros objects, do que usar a forma padrão de Javascripts.

Eu não sou um especialista em script java, mas aqui está um exemplo simples para entender a diferença entre “Object.create” e “new” ..

passo 1: crie a function pai com algumas propriedades e ações.

 function Person() { this.name = 'venkat'; this.address = 'dallas'; this.mobile='xxxxxxxxxx' } Person.prototype.func1 = function () { return this.name + this.address; } 

passo 2: crie uma function filho (PersonSalary) que se estenda acima da function Person usando New keyword.

 function PersonSalary() { Person.call(this); } PersonSalary.prototype = new Person(); PersonSalary(); 

passo 3: crie a segunda function filho (PersonLeaves) que se estende acima da function Person usando a palavra-chave Object.create .

 function PersonLeaves() { Person.call(this); } PersonLeaves.prototype = Object.create(Person.prototype); PersonLeaves(); 

// Agora, verifique os dois protótipos de funções filhas.

 PersonSalary.prototype PersonLeaves.prototype 

ambas as funções filho serão vinculadas ao protótipo Person (function pai) e poderão acessar seus methods, mas se você criar function filho usando new ele retornará um novo object com todas as propriedades pai das quais não precisamos e também quando você criar qualquer object ou function usando “New” que a function pai é executada que nós não queremos ser.

Aqui estão os tópicos

Se você quiser apenas delegar a alguns methods na function pai e não quiser que um novo object seja criado, é melhor usar o Object.create.