Comments on: for in Intrigue http://yuiblog.com/blog/2006/09/26/for-in-intrigue/ News and Artilces about Designing and Developing with Yahoo! Libraries. Sun, 11 May 2008 13:10:53 +0000 http://wordpress.org/?v=2.3.3 By: henrah http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-339433 henrah Fri, 04 Apr 2008 12:27:01 +0000 http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-339433 @Douglas: I know this article is 5 months old, but since it is being linked by JSLint, you should really fix that last code sample so that it doesn't return true for undefined keys. <code> function check_word(word) { return typeof words[word] !== 'function' && typeof words[word] !== 'undefined' } </code> @Douglas: I know this article is 5 months old, but since it is being linked by JSLint, you should really fix that last code sample so that it doesn’t return true for undefined keys.

function check_word(word) {
return typeof words[word] !== 'function'
&& typeof words[word] !== 'undefined'
}

]]>
By: GUYA.NET » Blog Archive » Resolving some issues with swfobject http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-224553 GUYA.NET » Blog Archive » Resolving some issues with swfobject Sun, 11 Nov 2007 18:17:17 +0000 http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-224553 [...] More related info about hasOwnProperty. [...] […] More related info about hasOwnProperty. […]

]]>
By: Garrett http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-189184 Garrett Tue, 11 Sep 2007 21:21:28 +0000 http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-189184 correction: For programmer-defined objects, <code>propertyIsEnumerable</code> is specified such that coforming implementations will have the exact same result as with <code>hasOwnProperty</code>. <code>var obj = { Garrett : "monkeybrains" ,borked : "javascript" // transitivity fixed :-) ,toString : function() { return "an enumerable prop"; } ,valueOf : function() { return 2; } // also enumerable. };</code> // can this be false for any value of s? (obj.hasOwnProperty( s ) != obj.propertyIsEnumerable( s )) correction:
For programmer-defined objects, propertyIsEnumerable is specified such that coforming implementations will have the exact same result as with hasOwnProperty.

var obj = {
Garrett : "monkeybrains"
,borked : "javascript" // transitivity fixed :-)
,toString : function() { return "an enumerable prop"; }
,valueOf : function() { return 2; } // also enumerable.
};

// can this be false for any value of s?
(obj.hasOwnProperty( s ) != obj.propertyIsEnumerable( s ))

]]>
By: Garrett http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-188494 Garrett Mon, 10 Sep 2007 07:42:01 +0000 http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-188494 Checking the object by using typeof can in no way be considered a replacement for <code>hasOwnProperty</code>. It is quite likely that a functional value exists in the iterated object's instance (a method). Using "in" will check the prototype chain. This feature can be useful for examining the prototype chain. For example, if you wanted to generically advise each method in a Panel class, you could iterate through all the functions in the object's prototype chain. If you think about it, it can be a useful feature. In fact, the "flaw" that Doug mentions is intentional behavior of the language. As mentioned in earlier comments, it is a perfectly valid feature (read above). Sweeney mentioned using propertyIsEnumerable to check an object's properties in lieu of missing hasOwnProperty. Interestingly, <code>propertyIsEnumerable</code> is specified such that coforming implementations will have the exact same result as with <code>hasOwnProperty</code>. Method <code>propertyIsEnumerable</code> does not check the prototype chain (15.2.4.7). Since all programmer-defined properties are enumerable. Therefore, <code>propertyIsEnumerable</code> provides the behavior that Doug so desires. The fact that <code>propertyIsEnumerable</code> does not check the prototype chain is itself a bug of the spec. David Flanagan pointed this out and Brendan will readily admit that it's a bug. JScript and SpiderMonkey both implement the spec correctly in this aspect. The fact that <code>propertyIsEnumerable</code> does not check the prototype chain is, in fact, a bug that Unfortunately, JScript suffers from another bug that causes <code>propertyIsEnumerable</code> to return false on a user-defined object property. This happens when the value that is passed to <code>propertyIsEnumerable</code> exists in the instance and overrides a non-enumerable (<code>DontEnum</code>) property in the object's prototype chain (such as an overridden "toString") Matthew Frank provides a tighter version of trim, and there's nothing wrong with adding <code>trim</code>, however, it should be done conditionally: <code>if(!String.prototype.trim) String.prototype.trim = function () { return this.replace(/^\s+|\s+$/g, ''); };</code> The conditional check is necessary because future versions of ECMAScript will have <code>String.prototype.trim</code>. @Andrew Dupont the <code>!==</code> will produce the same result as <code>!=</code> when both operands are string values (returns false if the sequence of characters is not an exact match,). I would probably opt for <code>!=</code> though. Checking the object by using typeof can in no way be considered a replacement for hasOwnProperty. It is quite likely that a functional value exists in the iterated object’s instance (a method).

Using “in” will check the prototype chain.

This feature can be useful for examining the prototype chain. For example, if you wanted to generically advise each method in a Panel
class, you could iterate through all the functions in the object’s prototype chain.
If you think about it, it can be a useful feature.

In fact, the “flaw” that Doug mentions is intentional behavior of the language. As mentioned in earlier comments, it is a perfectly valid feature (read above).

Sweeney mentioned using propertyIsEnumerable to check an object’s properties in lieu of missing hasOwnProperty.

Interestingly, propertyIsEnumerable is specified such that coforming implementations will have the exact same result as with hasOwnProperty.

Method propertyIsEnumerable does not check the prototype chain (15.2.4.7). Since all programmer-defined properties are enumerable. Therefore, propertyIsEnumerable provides the behavior that Doug so desires.

The fact that propertyIsEnumerable does not check the prototype chain is itself a bug of the spec. David Flanagan pointed this out and Brendan will readily admit that it’s a bug. JScript and SpiderMonkey both implement the spec correctly in this aspect.

The fact that propertyIsEnumerable does not check the prototype chain is, in fact, a bug that

Unfortunately, JScript suffers from another bug that causes propertyIsEnumerable to return false on a user-defined object property.

This happens when the value that is passed to propertyIsEnumerable exists in the instance and overrides a non-enumerable (DontEnum) property in the object’s prototype chain (such as an overridden “toString”)

Matthew Frank provides a tighter version of trim, and there’s nothing wrong with adding trim, however, it should be done conditionally:
if(!String.prototype.trim)
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g, '');
};

The conditional check is necessary because future versions of ECMAScript will have String.prototype.trim.

@Andrew Dupont the !== will produce the same result as != when both operands are string values (returns false if the sequence of characters is not an exact match,). I would probably opt for != though.

]]>
By: François B. http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-156315 François B. Thu, 12 Jul 2007 13:49:46 +0000 http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-156315 Hi Douglas ! Very interesting list of articles here. But I found a bug in your last code snippet that makes the function return true for undefined variables ! <code>var words = { 'foo' : 'foo', 'bar' : 'bar' } function check_word(word) { return typeof words[word] !== 'function'; } alert(check_word('foo')); // true alert(check_word('foobar')); // true !!! it should be false</code> So here is a quick correction : <code>function check_word(word) { return typeof words[word] !== 'undefined' && typeof words[word] !== 'function'; } alert(check_word('foo')); // true alert(check_word('foobar')); // false ! it's ok now</code> Hi Douglas !

Very interesting list of articles here.

But I found a bug in your last code snippet that makes the function return true for undefined variables !

var words = {
'foo' : 'foo',
'bar' : 'bar'
}
function check_word(word) {
return typeof words[word] !== 'function';
}
alert(check_word('foo')); // true
alert(check_word('foobar')); // true !!! it should be false

So here is a quick correction :

function check_word(word) {
return typeof words[word] !== 'undefined' &&
typeof words[word] !== 'function';
}
alert(check_word('foo')); // true
alert(check_word('foobar')); // false ! it's ok now

]]>
By: Jay http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-155910 Jay Wed, 11 Jul 2007 20:44:50 +0000 http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-155910 There is are two remote yet possible bugs in doing exactly as the article recommends. The first happens when the particular object whose properties one is enumerating has a custom property 'hasOwnProperty', and the second happens when Object.prototype is assigned a custom 'hasOwnProperty'. There is a workaround for the first bug. <code> for(var key in obj) { if(Object.prototype.hasOwnProperty.call(obj, key)) { ... } } </code> or, more compactly, <code> for(var key in obj) { if({ }.hasOwnProperty.call(obj, key)) { ... } } </code> This would be familiar if you've seen code like <code> var myargs = [ ].slice.call(arguments, 2); myfunc.apply(myobj, myargs); </code> There is are two remote yet possible bugs in doing exactly as the article recommends. The first happens when the particular object whose properties one is enumerating has a custom property ‘hasOwnProperty’, and the second happens when Object.prototype is assigned a custom ‘hasOwnProperty’. There is a workaround for the first bug.


for(var key in obj) {
if(Object.prototype.hasOwnProperty.call(obj, key)) {
...
}
}

or, more compactly,


for(var key in obj) {
if({ }.hasOwnProperty.call(obj, key)) {
...
}
}

This would be familiar if you’ve seen code like


var myargs = [ ].slice.call(arguments, 2);
myfunc.apply(myobj, myargs);

]]>
By: Brent Robientt http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-152577 Brent Robientt Thu, 05 Jul 2007 19:27:57 +0000 http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-152577 It seems like like the biggest problem with augmenting <code>Object.prototype</code> with new properties is that you pretty much never want include those properties when iterating over an object. So why not test against <code>Object.prototype</code> directly?: <code> for (name in obj) { if (Object.prototype[name] === undefined) { ... } } </code> It seems like like the biggest problem with augmenting Object.prototype with new properties is that you pretty much never want include those properties when iterating over an object. So why not test against Object.prototype directly?:

for (name in obj) {
if (Object.prototype[name] === undefined) {
...
}
}

]]>
By: VK http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-10129 VK Mon, 16 Oct 2006 13:48:57 +0000 http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-10129 JavaScript is not flawed with for-in loop just because this loops grabs all enumerable properties all along the inheritance chain: there can be situations where it is perfectly needed. JavaScript is flawed because we cannot manage isPropertyEnumerable flag, but only read it. That would be a years long dream of mine to be able to do something like: obj.someProperty = someValue; obj.someProperty.isEnumerable = false; Besides solving the for-in loop problem, it would be also a "cheap-chat" protected members emulation: not a bulletproof (as in any run-time compiled language) but very easy to use: obj.secretName = someFunction; obj.secretName.isEnumerable = false; Dreams, dreams... JavaScript is not flawed with for-in loop just because this loops grabs all enumerable properties all along the inheritance chain: there can be situations where it is perfectly needed.
JavaScript is flawed because we cannot manage isPropertyEnumerable flag, but only read it. That would be a years long dream of mine to be able to do something like:
obj.someProperty = someValue;
obj.someProperty.isEnumerable = false;

Besides solving the for-in loop problem, it would be also a “cheap-chat” protected members emulation: not a bulletproof (as in any run-time compiled language) but very easy to use:
obj.secretName = someFunction;
obj.secretName.isEnumerable = false;

Dreams, dreams…

]]>
By: Douglas Crockford http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-9471 Douglas Crockford Fri, 06 Oct 2006 22:37:00 +0000 http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-9471 !! converts a truthy value to true, and a value to false. It is similar to the Boolean() function. !! converts a truthy value to true, and a value to false. It is similar to the Boolean() function.

]]>
By: Bill http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-9465 Bill Fri, 06 Oct 2006 21:05:39 +0000 http://yuiblog.com/blog/2006/09/26/for-in-intrigue/#comment-9465 I have never seen the !! operator before - what does it do? I have never seen the !! operator before - what does it do?

]]>