Using the `in` operator with host objects

G

Garrett Smith

A bit of advice here regarding the `in` operator. In a nutshell: Avoid
doing that.

Avoid the <code>in</code> operator for host objects. Host objects use a
yet-unstandardized "catchall" behavior to "catch" property names during
get access, returning the value. Unfortunately, implementations vary.
Even within one browser, two objects may have different type of catchall
behavior. When "get" catchall behavior is implemented and "has" catchall
is not, the result is an object that, to its user, appears inconsistent,
contradicting itself by reporting that it does not have the property
while returning the property on get access.

<http://wiki.ecmascript.org/doku.php?id=strawman:catchalls>

Catchall Example:

// In Firefox 3.6 and below:
var p = navigator.plugins, ss = "Shockwave Flash";
s in p; // false
p[ss]; // [object Plugin]

// In Firefox 3.6 and below:
var f = document.forms[0], ss = "0";
s in f; // false;
f[ss]; // [object HTMLInputElement]

// In IE 8 and below:
var s = document.styleSheets, ii = "9999";
i in s; // true;
s[ii]; // Error.

It is generally safer to use the typeof operator and compare the result
against undefined.

var hasP = typeof obj.prop != "undefined";
 
D

David Mark

Garrett said:
A bit of advice here regarding the `in` operator. In a nutshell: Avoid
doing that.

Avoid the <code>in</code> operator for host objects. Host objects use a
yet-unstandardized "catchall" behavior to "catch" property names during
get access, returning the value. Unfortunately, implementations vary.
Even within one browser, two objects may have different type of catchall
behavior. When "get" catchall behavior is implemented and "has" catchall
is not, the result is an object that, to its user, appears inconsistent,
contradicting itself by reporting that it does not have the property
while returning the property on get access.

<http://wiki.ecmascript.org/doku.php?id=strawman:catchalls>

Catchall Example:

// In Firefox 3.6 and below:
var p = navigator.plugins, ss = "Shockwave Flash";
s in p; // false
p[ss]; // [object Plugin]

// In Firefox 3.6 and below:
var f = document.forms[0], ss = "0";
s in f; // false;
f[ss]; // [object HTMLInputElement]

// In IE 8 and below:
var s = document.styleSheets, ii = "9999";
i in s; // true;
s[ii]; // Error.

It is generally safer to use the typeof operator and compare the result
against undefined.

var hasP = typeof obj.prop != "undefined";

This pretty much concedes the point I have been making for years. But
the above example is not very robust. Best to use my isHost* functions.

http://www.cinsoft.net/host.html
 
G

Garrett Smith

David said:
Garrett said:
A bit of advice here regarding the `in` operator. In a nutshell: Avoid
doing that.
[...]

[...]
This pretty much concedes the point I have been making for years.

It explains the reason for why it doesn't work. See also Waldemar
Horwat's comments on the strawman page:

| ES5 relies on has, get, etc. being consistent with each other, has
| returning the same results if called twice, etc. The spec is not
| prepared to deal with contradictions in their results.

Programs should not have to deal with contradictions in their results.

The proposal should formalized and standardized in a way that host
objects can use catchall's and use them with results that are
non-contradictory.

You did not explain the reasons for why it doesn't work. My explanation
explains how catchalls work shows where they affect the `in` operator.
 
D

David Mark

Garrett said:
David said:
Garrett said:
A bit of advice here regarding the `in` operator. In a nutshell: Avoid
doing that.
[...]

[...]
This pretty much concedes the point I have been making for years.

It explains the reason for why it doesn't work. See also Waldemar
Horwat's comments on the strawman page:

| ES5 relies on has, get, etc. being consistent with each other, has
| returning the same results if called twice, etc. The spec is not
| prepared to deal with contradictions in their results.

Programs should not have to deal with contradictions in their results.

The proposal should formalized and standardized in a way that host
objects can use catchall's and use them with results that are
non-contradictory.

You did not explain the reasons for why it doesn't work. My explanation
explains how catchalls work shows where they affect the `in` operator.

It doesn't matter if I explained them or not. Like the "revelation"
about properties of ActiveX objects, and various other things over the
years, I ultimately turned out to be right (and you turned out to be
wrong). That's my point. ;)
 
T

Thomas 'PointedEars' Lahn

Garrett said:
A bit of advice here regarding the `in` operator [with host objects].
In a nutshell: Avoid doing that.
[...]
It is generally safer to use the typeof operator and compare the result
against undefined.

I believe I have been telling that for years. Well, better late than never.
The "catchall" probably makes it to a footnote in the ECMAScript Support
Matrix, though.


PointedEars
 
G

Garrett Smith

David said:
[...]
You did not explain the reasons for why it doesn't work. My explanation
explains how catchalls work shows where they affect the `in` operator.

It doesn't matter if I explained them or not. Like the "revelation"
about properties of ActiveX objects, and various other things over the
years, I ultimately turned out to be right (and you turned out to be
wrong). That's my point. ;)

Would a catchall be implemented with a method lookup, as:

if("createElement" in document) ;

An implementation wouldn't have a good reason to use a catchall for that.

A catchall would be used to try to get a value from an object, such as
with the indexed getters or name getters from collections such as
navigator.plugins.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top