views:

201

answers:

2

I'm seeing posts about a 'new' Object.create that makes enumeration configurable. However, it relies on a Object.defineProperty method. I can't find a cross browser implementation for this method.

Are we stuck writing for the old Object.create? I can't write things that won't work in IE6/7.

A: 

For what it's worth,

Object.defineProperty works in ie8 and FF4.

This means its worthwhile to feature sniff and implement it where it is useful seeing as you would hope the upgrade from ie 6/7 to 8/9 will occur in the next few years.

Another thing to be wary of is that the dontEnum property has a bug in JScript

You will have to work around the way you use the dontEnum property in IE.

[Edit]:

Here's documentation for Internet explorer and a link to the ES5 specification (Page 122 , 15.2.3.6)

Raynos
Thats good to know it's in IE8, I saw a glimpse what might have been an implementation. So, my question still being is there a published implementation of defineProperty?
Drew
There is no such implementation for ie6/7 I am afraid.
Raynos
@Drew: `Object.defineProperty` works *partially* IE8, you can use it only on *DOM Elements*. I've left an [answer](http://stackoverflow.com/questions/3830800/object-defineproperty-in-es5/3844768#3844768), which in short says: You can't. Property attributes can't be defined on ECMAScript 3-based implementations....
CMS
I didn't even notice it only works on DOM elements. Thanks for pointing that out.
Raynos
+3  A: 

There are several things that you can't emulate from the ECMAScript 5 Object.create method on an ECMAScript 3 environment.

As you saw, the properties argument will give you problems since in E3-based implementations there is no way to change the property attributes.

The Object.defineProperty method as @Raynos mentioned, works on IE8, but partially, it can be used only in DOM elements.

Also accessor properties will give you problems, they could be mimicked with widely supported non-standard methods such as __defineGetter__/__defineSetter__, but again, you can't change the property attributes.

Another problem aside the property descriptors, is that the Object.create method can accept null as an argument, to create an object that doesn't inherits from anything.

This can't be emulated with the Crockford's Object.create shim, because when the new operator is used with a constructor function that has a prototype property containing null -or any other non-object value-, the newly created object will inherit from Object.prototype anyway by default.

In some implementations -V8, Spidermonkey, Rhino, etc...- they have a setteable __proto__ property which could be used to set a null [[Prototype]], but again, that's non-standard, and for sure it will never work on IE.

I would recommend, if you want to target old browsers to don't use those features, since there is no way to make them work properly on those environments.

If you still want to use Object.create, without using the properties argument, you could, however I would recommend you to detect the things that can't be emulated.

The following would be a safer version of the 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;
    };
  })();
}

Anyway, use it carefully.

CMS