allow in operator for strings

RESOLVED WONTFIX

Status

()

--
enhancement
RESOLVED WONTFIX
12 years ago
12 years ago

People

(Reporter: stryker330, Unassigned)

Tracking

Trunk
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

12 years ago
Right now, the following throw exceptions:

'a' in 'abcde'
'a' in new String('abcde')

As far as I can decipher from the ECMAScript 3rd edition spec, this is valid - an exception should be thrown.

However, if the |in| operator is ever extended in functionality (see bug 368529), than it would make sense to allow strings to be the 2nd operand. Since it currently throws an exception, such a change would also be backwards-compatible.

Intuitively, if both x and y are strings, |x in y| would be true if x is a substring of y.
js> 'a' in new String('abcde')
false

Works fine for me.  The 'a' in 'abcde' throws per ECMA-262 Edition 3 as you note.

In ES4, 'a' in 'abcde' will not throw, but it too will evaluate to false.

Please don't file bugs asking for incompatible changes to SpiderMonkey. Do join the es4-discuss at mozilla.org list (mail to -request as usual with mailman) and make your pitch there.

Note also that specializing the |in| operator without changing |for-in| loops is a bad idea. Imitating Python so many years after Edition 3 added |in| is probably going to break scripts on the web, and add to confusion. But I will respond at greater length in bug 368529.

WONTFIX'ing for now.

/be
Status: NEW → RESOLVED
Last Resolved: 12 years ago
Resolution: --- → WONTFIX
(Reporter)

Comment 2

12 years ago
I didn't know that es4 mailing list exists - I'll post there in the future instead :)

Concerning the new String('abcde') example, you're right, it does work. I was testing it in IE7 to see what it does in that case and it throws an exception there. Apparently, I got the Firefox and IE7 results mixed up.

I'm actually requesting 2 things: one which is backwards compatible, and one that isn't.

1) The processing of the |in| operator to be similar to that of the for-in statement:

12.6.4 The for-in Statement 

The production IterationStatement : for ( LeftHandSideExpression in Expression ) Statement is evaluated as follows: 

1. Evaluate the Expression. 
2. Call GetValue(Result(1)). 
3. Call ToObject(Result(2)). 
...

11.8.7 The in operator 

The production RelationalExpression : RelationalExpression in ShiftExpression is evaluated as follows: 

1. Evaluate RelationalExpression. 
2. Call GetValue(Result(1)). 
3. Evaluate ShiftExpression. 
4. Call GetValue(Result(3)). 
5. If Result(4) is not an object, throw a TypeError exception. 
...

The suggested new processing of the |in| operator:

1. Evaluate RelationalExpression. 
2. Call GetValue(Result(1)). 
3. Evaluate ShiftExpression. 
4. Call GetValue(Result(3)). 
5. Call ToObject(Result(4)).
...

Or something like that. This is backwards compatible as far as I can tell.

2) |x in y| == true iff both x and y is a string and x is a substring of y. This is clearly backwards incompatible.
You need to log in before you can comment on or make changes to this bug.