ES4 draft: Object

Garrett Smith dhtmlkitchen at gmail.com
Thu May 15 15:48:18 PDT 2008


That sore thumb propertyIsEnumerable.

propertyIsEnumerable, as a setter, sets the DontEnum flag for the
object's own property. A value of 'false' makes the prop not show up
in - for in.
propertyIsEnumerable, as a getter, gets the value of the negation of
the DontEnum flag, and does not check the prototype chain. Has nothing
to do with whether or not the object shows up in - for in.

The addition adds a non-orthogonal aspect, apparently to add some
needed functionality.

This unituitive behavior is especially problematic to amateur, or
unskilled developers. The following code example from google
demonstrates this to be true:

http://doctype.googlecode.com/svn/trunk/goog/base.js

if (Object.prototype.propertyIsEnumerable) {
  /**
   * Safe way to test whether a property is enumarable.  It allows testing
   * for enumarable on objects where 'propertyIsEnumerable' is overridden or
   * does not exist (like DOM nodes in IE).
   * @param {Object} object The object to test if the property is enumerable.
   * @param {string} propName The property name to check for.
   * @return {boolean} True if the property is enumarable.
   * @private
   */
  goog.propertyIsEnumerable_ = function(object, propName) {
    return Object.prototype.propertyIsEnumerable.call(object, propName);
  };
} else {
  /**
   * Safe way to test whether a property is enumarable.  It allows testing
   * for enumarable on objects where 'propertyIsEnumerable' is overridden or
   * does not exist (like DOM nodes in IE).
   * @param {Object} object The object to test if the property is enumerable.
   * @param {string} propName The property name to check for.
   * @return {boolean} True if the property is enumarable.
   * @private
   */
  goog.propertyIsEnumerable_ = function(object, propName) {

    // KJS in Safari 2 is not ECMAScript compatible and lacks crucial methods
    // such as propertyIsEnumerable.  We therefore use a workaround.
    // Does anyone know a more efficient work around?

/ BROKEN: this approach checks the prototype chain with - if(propName in object)
// (gsmith)
    if (propName in object) {
      for (var key in object) {
        if (key == propName) {
          return true;
        }
      }
    }
    return false;
  };
}

Because we can see that the author appears to have made the assumption
that propertyIsEnumerable would check the prototype chain. This is a
perfectly natural assumption.

What is more confusing is that with the new proposal:

function X(){}
X.prototype = { p : true; };

var x = new x;
x.propertyIsEnumerable('p'); // false, p is in the [[Prototype]]
for(var prop in x)
  alert(prop); // alerts 'p'

Garrett

2008/3/17 Lars Hansen <lhansen at adobe.com>:
> Draft 3 of the spec for the Object class.  Changelog near the beginning.
> (Notably this version includes draft code for __createProperty__.)
>
> --lars
>
>
>
> _______________________________________________
> Es4-discuss mailing list
> Es4-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es4-discuss
>
>



More information about the Es4-discuss mailing list