2012-04-13 18 views
9

He estado leyendo sobre la cuña de Crockford para evitar la sobreescritura de prototipos, y entiendo que, a veces, no es la solución final. También entiendo que ES5 Shim puede ser una alternativa viable a esto. También leo this post which provides a more robust, secure alternative.Comprensión del objeto de Crockford.create shim

Aún así, me gustaría saber qué es 0imshim está "diciendo" y luego "haciendo". ¿Puede alguien decirme si los comentarios de mi explicación son correctos?

if (typeof Object.create === 'undefined') { 
//If the browser doesn't support Object.create 

    Object.create = function (o) { 
    //Object.create equals an anonymous function that accepts one parameter, 'o'. 

    function F() {}; 
    //Create a new function called 'F' which is just an empty object. 

    F.prototype = o; 
    //the prototype of the 'F' function should point to the 
    //parameter of the anonymous function. 

    return new F(); 
    //create a new constructor function based off of the 'F' function. 
    }; 
} 

//Then, based off of the 'Lost' example in the Crockford book... 

var another_stooge = Object.create(stooge); 

//'another_stooge' prototypes off of 'stooge' using new school Object.create. 
//But if the browser doesn't support Object.create, 
//'another_stooge' prototypes off of 'stooge' using the old school method. 

De esta manera, el prototipo del objeto 'títere' no se pueden sobrescribir cuando aumentamos cosas para 'another_stooge'. No es necesario reiniciar el prototipo de 'títere' con 'constructor'.

Gracias de antemano,

-k

Respuesta

14
if (typeof Object.create !== 'function') { 
    Object.create = function (o) { 
     function F() {} 
     F.prototype = o; 
     return new F(); 
    }; 
} 
var oldObject={prop:'Property_one' }; // An object 
var newObject = Object.create(oldObject); // Another object 

En el ejemplo anterior, hemos creado un nuevo objeto newObject usando create método que es una función miembro de Object objeto que hemos añadido en el objeto Object anteriormente en nuestro ejemplo (Crockford). Básicamente, lo que hace es que el método create declara una función F, un objeto vacío every function is a first class object in javascript y luego hemos heredado el prototipo de o (en ese caso o es también un objeto oldObject pasado como parámetro del método create) y finalmente hemos devuelto el nuevo objeto (una instancia de F) usando return new F(); a la variable newObject, por lo que ahora newObject es un objeto que heredó el oldObject. Ahora bien, si escribe console.log(newObject.prop);, obtendrá Property_one porque nuestro objeto newObject ha heredado el oldObject y es por eso que tenemos el valor de prop como Property_one. esto se conoce como herencia prototípica.

Debe pasar un objeto como parámetro del método create

+0

A-ha! Creo que lo tengo. Gracias Sheikh ... ¡tu ayuda es muy apreciada! – kaidez

+0

Eres el más bienvenido :-) –

0

único que hace es crear un nuevo constructor de objetos, que es F, entonces asignar el objeto pasado a la propiedad prototype del constructor para que el nuevo objeto creado con la El constructor F hereda esos métodos.

A continuación, utilizar el constructor para devolver un objeto recién inicializar (nueva F() => F.prototype)

Pero el Crockford dejar de reasignar el constructor adecuadamente ya que normalmente el nuevo constructor de objetos debe ser el mismo como el constructor de objetos heredado.

+0

Hi gillesc. ¡Gracias por responder! Entonces, cuando esto se usa, ¿eso significa que el prototipo del constructer necesita ser reiniciado? Algo como: stooge.prototype.constructor = títere; ¡Gracias de nuevo! – kaidez

0

En sus comentarios:

> //Object.create equals an anonymous function that accepts one parameter, 'o'. 

mejor decir que una función se asigna a la propiedad de createObject. Todas las funciones se pueden considerar anónimas, solo que algunas se asignan a propiedades o variables con nombre, otras no.

> //Create a new function called 'F' which is just an empty object. 

Declarar una función. Sí, es un objeto también.

>  F.prototype = o; 
>  //the prototype of the 'F' function should point to the 
>  //parameter of the anonymous function. 

Una referencia a o se asigna a F.prototype es un poco más corto para escribir.

>  //create a new constructor function based off of the 'F' function. 

No, debería ser "Devuelve una instancia de F". Entonces, el objeto devuelto tiene un [[Prototype]] interno que hace referencia al objeto pasado a la función. La parte desordenada es que se tuvo que crear una función F inútil para realizar el truco, y el constructor del objeto devuelto no tendrá un valor útil ya que hace referencia al F vacío.

No es que la propiedad del constructor sea muy confiable o particularmente útil normalmente de todos modos.

De esta manera, el prototipo del objeto 'títere' no se pueden sobrescribir cuando aumentamos cosas para 'another_stooge'. No es necesario reiniciar el prototipo "títere" usando 'constructor'.

Esa es una afirmación extraña. * another_stooge * tiene stooge ya que es privado [[Prototype]], no hereda de stooge.prototype pero de stooge.[[Prototype]].

Si desea que another_stooge herede de stooge.prototype, use Object.create(stooge.prototype) o Object.create(new stooge()), la primera es probablemente más adecuada.

Espero que todo tenga sentido.

+0

Hola RobG. ¡Gracias por responder! Tengo que releer para comprender completamente la sintaxis, pero ciertamente sé más de lo que sabía hace una hora. ¡Gracias de nuevo! – kaidez

0

Hay dos trucos aquí:

  1. F no es una función simple, es un constructor.
  2. "F.prototype" es solo una propiedad, no hace nada con la herencia en este momento. El verdadero truco es que cuando usamos "new F()", el "nuevo" crea un nuevo objeto, llama al constructor (que no hace nada aquí) Y establece el campo "prototipo" interno del nuevo objeto con el valor de "F.prototype", por lo que el objeto devuelto heredará de "o".

Así que creo que:

  • F es un constructor
  • F no se heredan de O
  • "nueva F" (que es el objeto devuelto) se heredan de O
-1

supongo nombrar la función interna como Object en lugar de F hace que el objeto resultante parezca más a lo Object.create() w ould crear

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