2010-08-10 31 views
7

Tengo un objeto, digamos son, que me gustaría heredar de otro objeto father.Agregar un prototipo a un objeto literal

Por supuesto que puede hacer una función constructora para el padre, como

Father = function() { 
    this.firstProperty = someValue; 
    this.secondProperty = someOtherValue; 
} 

y luego usar

var son = new Father(); 
son.thirdProperty = yetAnotherValue; 

pero esto no es exactamente lo que quiero. Como son va a tener muchas propiedades, sería más legible tener hijo declarado como un objeto literal. Pero entonces no sé cómo configurar su prototipo.

Hacer algo como

var father = { 
    firstProperty: someValue; 
    secondProperty: someOtherValue; 
}; 
var son = { 
    thirdProperty: yetAnotherValue 
}; 
son.constructor.prototype = father; 

no funcionará, ya que la cadena de prototipo parece estar oculta y no se preocupan por el cambio de constructor.prototype.

creo que puedo utilizar la propiedad __proto__ en Firefox, como

var father = { 
    firstProperty: someValue; 
    secondProperty: someOtherValue; 
}; 
var son = { 
    thirdProperty: yetAnotherValue 
    __proto__: father 
}; 
son.constructor.prototype = father; 

pero, por lo que yo entiendo, esto no es una característica estándar de la lengua y es mejor no utilizar directamente.

¿Hay alguna manera de especificar el prototipo para un objeto literal?

+0

http://stackoverflow.com/questions/1592384/adding-prototype-to-object-literal –

Respuesta

11

Tienes razón, __proto__ es una propiedad no estándar, y las dos únicas formas estándar que tiene que establecer un nuevo objeto de [[Prototype]], son:

  • A través del uso de un constructor y el new operador (como usted ya lo mencionó).
  • Usando el método ECMAScript 5 Object.create.

Object.create no widely supported es todavía (trabaja en IE9Pre3 +, Firefox 3.7Alpha +, Chrome 5+ Safari 5, Rhino 1.7), pero en algún momento todas las implementaciones conformarán la especificación ES5.

Puede tomar dos argumentos, el primero es el objeto que se utilizará como el [[Prototype]] del nuevo objeto, y el segundo, es otro objeto donde se pueden describir las propiedades propias (en la misma estructura que usted usaría Object.defineProperties).

Por ejemplo:

var father = { 
    firstProperty: 1, 
    secondProperty: 2 
}; 

var son = Object.create(father, { 
    thirdProperty: { 
    value: 'foo' 
    } 
}); 

father.isPrototypeOf(son); // true 
son.firstProperty; // 1 

El son interna [[Prototype]] propiedad se referirá a father, y contendrá una propiedad de valor denominado thirdProperty.

+1

Su respuesta aclara todas mis dudas, pero lamentablemente la sintaxis para Object.create (con el "valor agregado") parece aún menos legible – Andrea

+1

Sí, ¿por qué no podrían haber hecho una función que simplemente acepta un objeto literal? Quiero decir, la mayoría de las veces solo nos interesan las claves y los valores, no los metadatos de propiedad como hacerlo solo de lectura. –

-1

Especificar el prototipo para un objeto literal es un poco "wonky", ya que principalmente querrá el prototipo en objetos que cree utilizando la sintaxis del constructor (por ejemplo, nueva X()). No decir que esto no es posible ... pero es extraño. Un patrón similar que está bien probado (utilizado por jQuery, por ejemplo) es definir el prototipo como un objeto literal.Por ejemplo:

var X = function() {}; 
X.prototype = { 
    protoFunc1: function() {}, 
    protoFunc2: function() {} 
}; 
2

Eso es incorrecto jmar777. Si por ejemplo usted tiene

var X = function() {}; 
X.prototype = { 
    protoFunc1: function() { console.log('p1');}, 
    protoFunc2: function() { console.log('p2');} 
}; 

X.protoFunc1(); // is not a function 

Eso significa que lo que está haciendo:

X.prototype = {} 

es sólo la creación de un objeto llamado prototipo. No es el prototipo real. Para usar un prototipo, debes usar funciones de constructor.

Sin embargo, si lo modifica a este (método constructor)

function X(){}; 
X.prototype.protoFunc1 = function() { 
    console.log('p1'); 
} 
X.prototype.protoFunc2 = function() { 
    console.log('p2'); 
} 

var x = new X(); 
x.protoFunc1(); //'p1' 

que funcionaría.

Vaya al método literal del objeto sin usar el prototipo o use el método contructor usando el prototipo.

Cuestiones relacionadas