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