new - object.create javascript
Herencia de JavaScript: Object.create vs new (4)
En JavaScript, cuál es la diferencia entre estos dos ejemplos:
Requisito previo:
function SomeBaseClass(){
}
SomeBaseClass.prototype = {
doThis : function(){
},
doThat : function(){
}
}
Ejemplo de herencia A utilizando Object.create:
function MyClass(){
}
MyClass.prototype = Object.create(SomeBaseClass.prototype);
Ejemplo de herencia B usando la nueva palabra clave
function MyClass(){
}
MyClass.prototype = new SomeBaseClass();
Ambos ejemplos parecen hacer lo mismo. ¿Cuándo elegirías uno sobre el otro?
Una pregunta adicional: Considere el código en el siguiente enlace (línea 15), donde una referencia al propio constructor de la función se almacena en el prototipo. ¿Por qué es esto útil?
https://github.com/mrdoob/three.js/blob/master/src/loaders/ImageLoader.js
Extracto (si no desea abrir el enlace):
THREE.ImageLoader.prototype = {
constructor: THREE.ImageLoader
}
Ambos ejemplos parecen hacer lo mismo.
Eso es cierto en tu caso.
¿Cuándo elegirías uno sobre el otro?
Cuando SomeBaseClass
tiene un cuerpo de función, esto se ejecutará con la new
palabra clave. Por lo general, esto no está destinado; solo desea configurar la cadena de prototipos. En algunos casos, incluso podría causar problemas graves porque crea una instancia de un objeto, cuyas variables de ámbito privado son compartidas por todas las instancias de MyClass
, ya que heredan los mismos métodos privilegiados. Otros efectos secundarios son imaginables.
Por lo tanto, generalmente debería preferir Object.create
. Sin embargo, no es compatible con algunos navegadores heredados; que es la razón por la que ve el new
enfoque: demasiado frecuente, ya que a menudo no causa daños (obvios). También eche un vistazo a esta respuesta .
En su pregunta, ha mencionado que Both examples seem to do the same thing
No es cierto en absoluto, porque
Tu primer ejemplo
function SomeBaseClass(){...}
SomeBaseClass.prototype = {
doThis : function(){...},
doThat : function(){...}
}
function MyClass(){...}
MyClass.prototype = Object.create(SomeBaseClass.prototype);
En este ejemplo, solo estás heredando SomeBaseClass'' prototype
pero ¿qué SomeBaseClass'' prototype
si tienes una propiedad en SomeBaseClass
function SomeBaseClass(){
this.publicProperty=''SomeValue'';
}
y si lo usa como
var obj=new MyClass();
console.log(obj.publicProperty); // undefined
console.log(obj);
El objeto obj
no tendrá propiedad publicProperty
como en este ejemplo .
Tu segundo ejemplo
MyClass.prototype = new SomeBaseClass();
Está ejecutando la función constructor
, creando una instancia de SomeBaseClass
y heredando todo el objeto SomeBaseClass
. Entonces, si usas
var obj=new MyClass();
console.log(obj.publicProperty); // SomeValue
console.log(obj);
En este caso, su propiedad publicProperty
también está disponible para el objeto obj
como en este ejemplo .
Dado que Object.create
no está disponible en algunos navegadores antiguos, en ese caso puede usar
if(!Object.create)
{
Object.create=function(o){
function F(){}
F.prototype=o;
return new F();
}
}
El código anterior solo agrega la función Object.create
si no está disponible para que pueda usar la función Object.create
y creo que el código anterior describe lo que Object.create
realmente hace. Espero que ayude de alguna manera.
La diferencia se vuelve obvia si usa Object.create()
como está previsto. En realidad, oculta completamente la palabra prototype
de tu código, hará el trabajo bajo el capó. Usando Object.create()
, podemos ir como
var base = {
doThis : function(){
},
doThat : function(){
}
};
Y luego podemos extender / heredar otros objetos de este
var myObject = Object.create( base );
// myObject will now link to "base" via the prototype chain internally
Así que este es otro concepto, una forma más "orientada a objetos" de inherting. No hay una "función de constructor" lista para usar usando Object.create()
por ejemplo. Pero, por supuesto, podría simplemente crear y llamar a una función de constructor autodefinida dentro de esos objetos.
Un argumento para usar Object.create()
es que podría parecer más natural mezclar / * heredar * de otros objetos, que usar el modo predeterminado de Javascripts.
No soy un experto en script java pero aquí hay un ejemplo simple para entender la diferencia entre "Object.create" y "new".
paso 1: crea la función principal con algunas propiedades y acciones.
function Person() {
this.name = ''venkat'';
this.address = ''dallas'';
this.mobile=''xxxxxxxxxx''
}
Person.prototype.func1 = function () {
return this.name + this.address;
}
paso 2: crea una función hija (PersonSalary) que se extiende por encima de la función Person usando New keyword ..
function PersonSalary() {
Person.call(this);
}
PersonSalary.prototype = new Person();
PersonSalary();
paso 3: crear la segunda función secundaria (PersonLeaves) que se extiende por encima de la función Person utilizando la palabra clave Object.create .
function PersonLeaves() {
Person.call(this);
}
PersonLeaves.prototype = Object.create(Person.prototype);
PersonLeaves();
// Ahora comprueba ambos prototipos de funciones infantiles.
PersonSalary.prototype
PersonLeaves.prototype
Ambas funciones secundarias se vincularán con el prototipo de Persona (función principal) y pueden acceder a sus métodos, pero si crea una función hija usando nueva, devolverá un objeto completamente nuevo con todas las propiedades principales que no necesitamos y también cuando cree cualquier Objeto o función usando "Nuevo" esa función primaria se ejecuta y no queremos que sea.
Aquí están los detalles
si solo desea delegar en algunos métodos en la función primaria y no desea que se cree un nuevo objeto, usar Object.create es la mejor manera.