recorrer programacion orientado orientada objetos objeto imprimir dinamico crear array agregar javascript object prototypal-inheritance creation

javascript - programacion - ¿Qué está pasando en la técnica de creación de objetos de Crockford?



recorrer objeto json javascript (4)

Solo hay 3 líneas de código y, sin embargo, tengo problemas para comprender esto:

Object.create = function (o) { function F() {} F.prototype = o; return new F(); }; newObject = Object.create(oldObject);

(De herencia prototípica )

  1. Object.create() comienza creando una función vacía llamada F Estoy pensando que una función es un tipo de objeto. ¿Dónde se almacena este objeto F ? A nivel mundial supongo.

  2. A continuación, nuestro objeto oldObject , pasado como o , se convierte en el prototipo de la función F La función (es decir, el objeto) F ahora "hereda" de nuestro objeto oldObject , en el sentido de que la resolución de nombres se oldObject través de él. Bien, pero tengo curiosidad por saber cuál es el prototipo predeterminado para un objeto, ¿Objeto? ¿Es eso también cierto para una función-objeto?

  3. Finalmente, F se newObject instancia y se devuelve, convirtiéndose en nuestro newObject . ¿Es la new operación estrictamente necesaria aquí? ¿ F ya no proporciona lo que necesitamos, o hay una diferencia crítica entre los objetos de función y los objetos de no función? Claramente, no será posible tener una función de constructor utilizando esta técnica.

¿Qué sucede la próxima vez que se Object.create() ? ¿Se sobrescribe la función global F ? Seguramente no se reutiliza, ya que eso alteraría los objetos previamente configurados. ¿Y qué sucede si varios subprocesos llaman a Object.create() , hay algún tipo de sincronización para evitar las condiciones de carrera en F ?


> Claramente, no será posible tener una función de constructor usando esta técnica.

La técnica ya es un constructor de objetos, ya que devuelve una nueva F (), pero no se pueden establecer valores de propiedad como para decir new man (''John'', ''Smith''). Sin embargo, si se modifica el código Object.create, es posible crear instancias. Por ejemplo, el objeto sarah a continuación se puede construir e instanciar con Object.creator, y heredará el método getName.

var girl = { name: '''', traits: {}, getName: function(){return this.name} } var sarah = Object.creator(girl, ''Sarah'', {age:29,weight:90})

El objeto sarah consistirá entonces en propiedades propias {nombre: ''Sarah'', rasgos: {edad: 9, peso: 49}}, y el prototipo heredado sarah.getName () producirá ''Sarah''.

El siguiente método se basa en las propiedades propias que enumeran con ''for (prop in o)'' en el orden de creación. Aunque no está garantizado por las especificaciones de ECMA, este ejemplo (y algunos más complejos) funcionó para todos los principales navegadores (4) probados, se usó hasOwnProperty (), de lo contrario no se usó.

Object.creator = function(o) { var makeArgs = arguments function F() { var prop, i=1, arg, val for(prop in o) { if(!o.hasOwnProperty(prop)) continue val = o[prop] arg = makeArgs[i++] if(typeof arg === ''undefined'') break this[prop] = arg } } F.prototype = o return new F() }

El ECMA Object.create oficial tiene un segundo parámetro opcional, propertiesObject, que puede instanciar los valores de las propiedades, pero es un objeto en lugar de la lista habitual, y su uso es incómodo. Por ejemplo, yo creo:

o2 = Object.create({}, { p: { value: 42, writable: true, enumerable: true, configurable: true } });

es equivalente a la forma antigua mucho más simple: -

o2 = new function(p) { this.p=p }(42)

y

o2 = Object.creator({p:''''}, 42)


1) Object.create () comienza creando una función vacía llamada F. Estoy pensando que una función es un tipo de objeto. ¿Dónde se almacena este objeto F? A nivel mundial supongo.

No, se almacena en el ámbito local de la función Object.create , cada vez que invoque Object.create volverá a crear esta función F

Incluso podría crear una implementación más eficiente en memoria almacenando F en un cierre y reutilizándola:

if (typeof Object.create !== "function") { Object.create = (function () { function F() {} // created only once return function (o) { F.prototype = o; // reused on each invocation return new F(); }; })(); }

2) Luego, nuestro objeto antiguo, pasado como o, se convierte en el prototipo de la función F. La función (es decir, el objeto) F ahora "hereda" de nuestro objeto antiguo, en el sentido de que la resolución de nombres se enrutará a través de él. Bien, pero tengo curiosidad por saber cuál es el prototipo predeterminado para un objeto, ¿Objeto? ¿Es eso también cierto para una función-objeto?

Todos los objetos tienen una propiedad interna que crea la cadena de prototipos, esta propiedad se conoce como [[Prototype]] , es una propiedad interna, aunque algunas implementaciones le permiten acceder a ella, como mozilla, con la propiedad obj.__proto__ .

El [[Prototype]] predeterminado [[Prototype]] cuando crea un nuevo objeto, es decir, var obj = {}; es Object.prototype .

Todas las funciones tienen una propiedad de prototype , esta propiedad se usa cuando una función se usa como un Constructor , invocado con el new operador.

Se creó una nueva instancia de objeto detrás de escena, y este objeto [[Prototype]] se establece en la propiedad prototype su Constructor.

3) Finalmente, F se crea una instancia y se devuelve, convirtiéndose en nuestro nuevo Objeto. ¿Es estrictamente necesaria la "nueva" operación aquí? ¿F ya no proporciona lo que necesitamos, o hay una diferencia crítica entre los objetos de función y los objetos de no función? Claramente, no será posible tener una función de constructor utilizando esta técnica.

Sí, el new operador es esencial en este método.

El new operador es la única forma estándar de establecer la propiedad interna [[Prototype]] de un objeto, si tiene curiosidad acerca de cómo funciona, puede echar un vistazo a la operación interna [[Construct]] .

¿Qué sucede la próxima vez que se llame a Object.create ()? ¿Se sobrescribe la función global F? Seguramente no se reutiliza, ya que eso alteraría los objetos previamente configurados. ¿Y qué sucede si varios subprocesos llaman a Object.create (), hay algún tipo de sincronización para evitar las condiciones de carrera en F?

La próxima vez que se invoque Object.create , una nueva función local de F se Object.create una instancia solo dentro del alcance de la llamada al método, no debe preocuparse por las condiciones de la carrera .

Tenga en cuenta que esta implementación apenas cumple con el Object.create descrito en la [[Construct]] ; en ese método, podría pasar un descriptor de propiedad para inicializar el objeto.

Todos los proveedores de navegadores lo están implementando (ya disponible en Firefox 3.7 alfas, la última versión de Wekit Nightly Builds y Chrome 5 Beta), por lo que le recomendaría al menos que verifique si existe una implementación nativa antes de anularla.


1) Una función es de hecho un tipo de objeto. Se crea un objeto de función con el identificador F cada vez que se llama a Object.create , y solo se puede acceder con ese identificador dentro de esa ejecución de Object.create . Por lo tanto, cada vez que se llama Object.create , se obtiene un objeto de función F diferente. Este objeto de función se Object.create como la propiedad del constructor del objeto devuelto por Object.create .

2)

F ahora "hereda" de nuestro objeto antiguo, en el sentido de que la resolución de nombres se enrutará a través de él

Esto no es realmente correcto. Asignar un objeto someObject a la propiedad prototype de una función solo significa que el prototipo de cualquier objeto futuro creado al llamar a esta función como un constructor será someObject .

3) Lo new es absolutamente vital para esta técnica. Solo al llamar a una función como constructor produce un nuevo objeto, y el prototipo de ese objeto (que generalmente no es accesible) se establece en la propiedad prototype la función de constructor. No hay otra forma (estandarizada) de configurar un prototipo de objeto.

Finalmente, JavaScript en los navegadores es de un solo hilo, por lo que las condiciones de carrera como las que describe no son posibles.


Su principal malentendido aquí es que F tiene alcance global. Se declara en el cuerpo de Object.create y, por consiguiente, solo está dentro del alcance dentro de ese bloque de método.