2012-04-27 28 views
5

Por favor, ayúdame a comprender este fragmento de código.Javascript object inheritance

var person = { 
    'first-name': 'FirstName', 
    'last-name': 'LastName', 
    'gender': 'Male' 
}; 

var anotherPerson = new Object(person); 
anotherPerson.desig = 'Designation'; 

console.log('Another person designation: ' + anotherPerson['desig'] + ', person designation: ' + person['desig']); 

que esperaba que la salida sea Another person designation: Designation, person designation: undefined pero para mi sorpresa, me pareció que estaba `Another person designation: Designation, person designation: Designation.

Según me anotherPerson está extendiendo person objeto y propiedades ajustado a anotherPerson no debe ser visible a person objeto. ¿Me equivoco aquí? ¿O es que ambos el objeto apuntan a la misma ubicación?

[EDIT]

Ahora bien, hay muchas más sorpresas.

Agregué el siguiente código a lo anterior.

person.place = 'XYZ'; 
console.log(person['place'] + ', ' + anotherPerson['place']); // Expected: XYZ, undefined. Result: XYZ, XYZ. 

Con base en el resultado y respuestas anteriores pensé que ambos objetos se refieren a la misma ubicación. Ahora agregué algunas líneas más

person = undefined; 
console.log(anotherPerson['place']) //Expected: error, Result: XYZ. ??!?!? 
console.log(person['place']) // Expected: error, Result: error. 

¿Puede alguien arrojar algo de luz sobre mí para entender esto? Gracias por su ayuda de antemano

+0

No hay herencia aquí. Solo dos referencias al mismo objeto. – Cameron

+0

Entonces, ¿cómo puedes clonar el objeto y crear uno nuevo? Yo, como el OP probablemente, supuse que lo nuevo sería un NUEVO objeto. – DanRedux

+0

Ver: http://stackoverflow.com/questions/728360/copying-an-object-in-javascript –

Respuesta

2

No está haciendo extensiones ni ningún tipo de herencia.

Esto se acerca:

var Person = function() { 
    this["first-name"] = 'FirstName', 
    this["last-name"] = 'LastName', 
    this["gender"] = 'Male' 
}; 

var person = new Person(); 
var anotherPerson = new Person(); 

Ahora usted tiene dos casos separados de Person. Si también desea anotherPerson ser una subclase ..

var Person = function() { 
    this["first-name"] = 'FirstName', 
    this["last-name"] = 'LastName', 
    this["gender"] = 'Male' 
}; 

var AnotherPerson = function() { 
    this.desig = "Designation"; 
} 
AnotherPerson.prototype = new Person(); // inherit from Person 
AnotherPerson.prototype.constructor = AnotherPerson; // reset constructor 

var person = new Person(); 
var anotherPerson = new AnotherPerson(); 

console.log(person.desig); // undefined 
console.log(anotherPerson.desig); // Designation 
+1

Acababa de escribir el mismo primer bloque de código;) +1 – bhamlin

+0

@Frits Gracias por su respuesta. Obtengo el código que has explicado. Entonces, cuando hacemos 'new Object (persona)' ¿es que 'anotherPerson' se refiere a la misma ubicación? Traté de agregar una nueva propiedad a 'person' y' anotherPerson' fue capaz de leer esa nueva propiedad con éxito. ¿Por que es esto entonces? – Anji

+0

No estoy del todo seguro de lo que 'nuevo Objeto (persona)' hace ... ¿tal vez se resuelva como 'persona'? Sé que no se extiende mágicamente desde 'persona ': P – Halcyon

0
No

realmente una solución, pero para mí, esto es cómo clonar un objeto de una manera tal que puedo extenderla:

var anotherPerson = new Object(); 
for(i in person) anotherPerson[i]=person[i]; 

En lugar de

var anotherPerson = new Object(person); 

Luego funciona como se esperaba.

+0

¿Puedo saber qué ocurre exactamente cuando hacemos 'var anotherPerson = new Object (persona)'? – Anji

0

La función Object (nota: la misma, aún más sorprendente si usted no está familiarizado con lo que está pasando, se aplica a llamar new Object(...)) no crea un objeto nuevo si se pasa algo que no es de tipo booleano, numérico o de cadena; simplemente devuelve el objeto ya existente. (Razón:. Porque ya es un objeto Casi todo es un objeto en Javascript.)

Por lo tanto, anotherPerson es el mismo objeto exacto como person, así que cuando lo modifica permite modificar person también.

No afirmo que este sea un comportamiento sensato; pero es lo que define la especificación del lenguaje.

0

Si desea extender/heredar un objeto, puede hacerlo

var person = { 
    'first-name': 'FirstName', 
    'last-name': 'LastName', 
    'gender': 'Male' 
}; 
if (typeof Object.create !== 'function') 
{ 
    Object.create=function(o) 
    { 
     function F(){} 
     F.prototype=o; 
     return new F(); 
    } 
} 
var newPerson=Object.create(person); 
newPerson.age=25; 
newPerson.gender="Female"; 

console.log(person.gender); // Male 
console.log(newPerson.gender); // Female 

console.log(person.age); // undefined 
console.log(newPerson.age); // 25 

Fiddle

Referencia:Prototypal Inheritance in JavaScript

+0

¡La manera de Douglas Crockford! Perfecto. – Anji

+0

Sí, eso es correcto. –

0

una solución general para la implementación herencia en JavaScript

function inherits(base, extension) 
{ 
    for (var property in base) 
    { 
     try 
     { 
     extension[property] = base[property]; 
     } 
     catch(warning){} 
    } 
} 
+0

¿Por qué intentar/capturar? – alex