2010-09-30 15 views
8

Veo publicaciones sobre un 'nuevo' Object.create que hace la enumeración configurable. Sin embargo, se basa en un método Object.defineProperty. No puedo encontrar una implementación de navegador cruzado para este método.Object.defineProperty en ES5?

¿Estamos atrapados escribiendo para el antiguo Object.create? No puedo escribir cosas que no funcionen en IE6/7.

+3

¡Siempre hay un marco de Chrome! – kzh

Respuesta

14

Hay varias cosas que no se puede emular desde la Object.create método de ECMAScript 5 en un entorno ECMAScript 3.

Como viste, el argumento de las propiedades te dará problemas ya que en las implementaciones basadas en E3 hay de ninguna manera para cambiar los atributos de la propiedad.

Los Object.defineProperty método como @Raynos mencionados, funciona en IE8, pero parcialmente, que se puede utilizar solamente en elementos DOM.

también propiedades de descriptor de acceso le dará problemas, que podría ser imitado con métodos no estándar ampliamente compatibles, como __defineGetter__/__defineSetter__, pero de nuevo, no puede cambiar los atributos de la propiedad.

Otro problema aparte de los descriptores de propiedad, es que el método Object.create puede aceptar null como argumento, para crear un objeto que no hereda de nada.

Esto no puede ser emulada con la Crockford's Object.create shim, porque cuando el operador new se utiliza con una función constructora que tiene una propiedad que contiene prototypenull -o cualquier otro de valor no-objeto, el objeto recién creado heredará del Object.prototype de todos modos por defecto.

En algunas implementaciones -v8, Mono Araña, Rhino, etc ...- tienen un setteable __proto__ propiedad que podría ser utilizado para fijar un null [[Prototype]], pero de nuevo, eso es no estándar, y de seguro nunca funcionará en IE.

Recomendaría, si desea orientar los navegadores antiguos para que no utilicen esas características, ya que no hay forma de que funcionen correctamente en esos entornos.

Si aún desea utilizar Object.create, sin necesidad de utilizar las propiedades argumento, se puede, sin embargo, recomendaría usted para detectar las cosas que no pueden ser emuladas.

La siguiente sería una versión más segura del Crockford's Object.create shim:

if (typeof Object.create != 'function') { 
    (function() { 
    var F = function() {}; 
    Object.create = function (o) { 
     if (arguments.length > 1) { throw Error('Second argument not supported');} 
     if (o === null) { throw Error('Cannot set a null [[Prototype]]');} 
     if (typeof o != 'object') { throw TypeError('Argument must be an object');} 
     F.prototype = o; 
     return new F; 
    }; 
    })(); 
} 

De todos modos, utilizar con cuidado.

2

Por lo que vale la pena,

Object.defineProperty obras en IE8 y FF4.

Esto significa que merece la pena oler e implementarlo donde sea útil, ya que es de esperar que la actualización de, por ejemplo, 6/7 a 8/9 ocurra en los próximos años.

Otra cosa a tener cuidado de que la propiedad es dontEnum tiene un error en JScript

Usted tendrá que trabajar en torno a la forma en que utiliza la propiedad dontEnum en IE.

[Editar]:

Aquí está la documentación para Internet explorer y un enlace a la ES5 specification (Página 122, 15.2.3.6)

+0

Eso es bueno saber que está en IE8, vi un vistazo de lo que podría haber sido una implementación. Entonces, mi pregunta sigue siendo ¿hay una implementación publicada de defineProperty? – Drew

+0

No existe tal implementación para ie6/7, me temo. – Raynos

+4

@Drew: 'Object.defineProperty' funciona * parcialmente * IE8, puede usarlo solo en * DOM Elements *. He dejado una [respuesta] (http://stackoverflow.com/questions/3830800/object-defineproperty-in-es5/3844768#3844768), que en resumen dice: No se puede. Los atributos de propiedad no pueden definirse en las implementaciones basadas en ECMAScript 3 .... – CMS

4

Si quieres una buena aplicación defineProperty(), echar un vistazo a https://github.com/kriskowal/es5-shim

Por desgracia, no se puede hacer la enumeración configurable en un entorno ES3. Esta corrección le permitirá llamar a la API en cualquier entorno, pero las propiedades seguirán siendo enumerables en ES3.

+0

Eso es realmente genial, gracias – Drew

Cuestiones relacionadas