2012-09-30 7 views
14

A menudo se dice que cada objeto Javascript tiene una propiedad prototype, pero me parece que foo.prototype tiene un valor solo si foo es una función.Se dice que todos los objetos Javascript tienen una propiedad de prototipo, pero solo veo foo.prototype si foo es una función?

En Chrome y Firefox, obj.__proto__ tiene un valor - ¿es esta la propiedad dicha prototype? Pero en IE 9, no funcionará (¿hay alguna forma que pueda?), Y pensé que por prototype propiedad, eso significa que obj.prototype debería funcionar?

entiendo que Object.getPrototypeOf(obj) parece mostrar esta prototype propiedad, pero ¿por qué necesita un método especial para conseguirlo? ¿Por qué no simplemente como person.name, que es obtener la propiedad name del objeto person?


Actualización: por cierto, obj.constructor.prototype parece veces ser ese prototipo, pero a veces no, como en el siguiente código de hecho con herencia de prototipos con ningún constructor: (este método es en el Pro Javascript Patrones de diseño libro de Harmes y Díaz por Apress 2008, p. 46)

var Person = { 
    name: 'default value', 
    getName: function() { 
     return this.name; 
    } 
} 

var reader = clone(Person); 
console.log(reader.getName()); 
reader.name = "Ang Lee"; 
console.log(reader.getName()); 

function clone(obj) { 
    function F() {}; 
    F.prototype = obj; 
    return new F; 
} 

console.log("the prototype of reader is", Object.getPrototypeOf(reader)); 

console.log(Object.getPrototypeOf(reader) === reader.constructor.prototype); 
console.log(Object.getPrototypeOf(reader) == reader.constructor.prototype); 

console.log(Object.getPrototypeOf(reader) === reader.__proto__); 
console.log(Object.getPrototypeOf(reader) == reader.__proto__); 

el resultado mostrará falso, falso, cierto, cierto desde hace 4 líneas.

+2

Todos los objetos están relacionados con un prototipo, pero no necesariamente por una propiedad visible. En otras palabras, las partes internas del tiempo de ejecución de JavaScript saben cuál es el objeto prototipo, pero es posible que su código no pueda determinar cuál es. En cuanto a * por qué * eso es cierto, bueno, es solo la forma en que se implementó JavaScript. – Pointy

+2

Cualquiera que diga "cada objeto JavaScript tiene una propiedad prototipo" se refiere a la propiedad interna (expuesta como '__proto__' en la mayoría de los navegadores, como usted mencionó). –

+1

Eche un vistazo a esta pregunta similar: http://stackoverflow.com/questions/9451881/ –

Respuesta

13

objeto Cada JavaScript tiene un "prototipo" interno propiedad, a menudo llamado [[Prototype]], que apunta al objeto del que hereda directamente. Esto está expuesto en FF y Chrome por la propiedad no estándar __proto__. Object.getPrototypeOf es un getter para esta propiedad interna.

Cada función de JavaScript [objeto] tiene una propiedad prototype, que se inicializa con un objeto [casi] vacío. Cuando crea una nueva instancia de esta función llamándola como un constructor, el [[prototipo]] de ese nuevo objeto apuntará al objeto prototype del constructor.

Si obtiene el [[prototipo]] de una función (cada función es un objeto, entonces tiene una), dará como resultado el objeto Function.prototype del cual las funciones heredan sus métodos (como bind, call, apply etc) Ver también Why functions prototype is chained repeatedly? en eso.

+0

¿te refieres con el objeto "casi" vacío? ¿Cómo es que pusiste el corchete? –

+4

El objeto casi vacío tiene una propiedad no enumerable 'constructor', que apunta a la función de constructor. La notación con los corchetes dobles proviene de la [especificación EcmaScript oficial] (http://ecma-international.org/ecma-262/5.1/#sec-8.6.2) que utiliza este formato para todas las propiedades internas. – Bergi

+0

¿Qué pasa con la notación de corchete "único" como el tuyo? [casi] vacío –

3

Es el constructor de cada Objeto que tiene un prototype. Así que para algunos foo, bar o foobar:

var foo = {}; 
console.log(foo.constructor.prototype); //=> Object 
var bar = 5; 
console.log(bar.constructor.prototype); //=> Number 
function Foobar(){} 
var foobar = new Foobar; //Foobar used a constructor 
console.log(foobar.constructor.prototype); //=> Foobar 
+0

aha, a veces la forma del constructor no funciona, parece, por favor, consulte la actualización en la pregunta –

+0

@ 動靜 能量 Es por eso que ve personas actualizando manualmente el constructor cuando hacen una herencia prototípica ... algo así como '(F.prototype = obj) .constructor = F;' –

Cuestiones relacionadas