in, instanceof and primitive values?

A

Asen Bozhilov

I have a simple question. When i have code like this:

var str = 'primitive string value';
str.length;

In ECMA 262-3:

| 11.2.1 Property Accessors
| 1. Evaluate MemberExpression.
| 2. Call GetValue(Result(1)).
| 3. Evaluate Expression.
| 4. Call GetValue(Result(3)).
| 5. Call ToObject(Result(2)).
| 6. Call ToString(Result(4)).
| 7. Return a value of type Reference whose base object is
| Result(5) and whose property name is Result(6).

In the step 5 primitive value will be convert to `object' by
algorithm defined in 9.9 ToObject. In my case will be create
intermediate String object whose [[value]] property is set to the
value of the string.
But what will be happen with relational operators `in' and
`instanceof':

window.alert('string' instanceof String); //false
window.alert('slice' in 'string'); //throw TypeError

Absolutely expected behavior, but my question isn't about that. My
question is, why is that design of `in' and `instanceof' operators.
Why don't coerced primitive values to `object'?

Thanks for responses.
Regards.
 
G

Garrett Smith

Asen said:
I have a simple question. When i have code like this:
[snip]

But what will be happen with relational operators `in' and
`instanceof':

window.alert('string' instanceof String); //false
window.alert('slice' in 'string'); //throw TypeError

Absolutely expected behavior, but my question isn't about that. My
question is, why is that design of `in' and `instanceof' operators.
Why don't coerced primitive values to `object'?

For instanceof, the behavior correct; a string value is not an instance
of String.

For the in Operator, I don't see why the TypeError is useful. ToObject
could be used on the right-side operand.

It hypothetically could be used as:
"trim" in "foo";

That throws a typeerror. That seems unnecessary. I can't see why calling
ToObject on the right-side value would be a problem. There may be a
problem, but I don't know what it is.
 
D

Dmitry A. Soshnikov

[...]
why is that design of `in' and `instanceof' operators.
Why don't coerced primitive values to `object'?

Yep, behavior is expected (by corresponding algorithms), but
ECMA-262-3 doesn't clarify this moments, they just did it so. In some
cases there're conversions, e.g. like `ToObject` with property
accessors or with the equals operator, which calls vice versa
`ToPrimitive` for the object:

'a' == new String('a'); // true

in other cases there're no such conversions, but they can be done
manually:

Object('a') instanceof String; // true

The case with property accessors which calls `ToObject` is the key for
the phrase that "everything in ES is an object" which is often appears
in some ES-articles, but sure, not "everything", but "almost
everything and depending on type conversion".

Why they didn't make the same for the `in` and `instanceof` operators?
We just can guess (btw, we can ask e.g. B.Eich for that). I think for
to show the exact difference between primitives and object, to show,
that there *are* still primitives and objects (meanwhile, "everything
in ES is an object"). But for the property accessors it's just the
useful sugar to show that primitives can *correspond with* the related
object and *inherit from* the related object type. But having this,
there should be still difference that primitives are not objects, and
`in` and `instanceof` show that.
 
A

Asen Bozhilov

Garrett said:
For instanceof, the behavior correct; a string value is not an instance
of String.

Yes, but confusion come when type code like this one:

var str = 'string';
str.constructor === String; //true
^^^
Automatic coerced ToObject(str) and after that, intermediate `object'
is instance of String. Moreover:

str.__proto__ === String.prototype; //true

Again expected behavior by Property Accessors.
For the in Operator, I don't see why the TypeError is useful. ToObject
could be used on the right-side operand.

It hypothetically could be used as:
"trim" in "foo";

Only reason that i see is, hard to understand code when someone read
it.

'Garrett' in 'Garrett Smith';

Expected behavior in first look is similar of `indexOf'. But actually
is totally different.

'Garrett' in Object('Garrett Smith');

That is more intuitive for `in' keyword and specified algorithm for
`in' operator in ECMA 262-3.

But what are you expect when `in' operators been used for array
literal?

'Garrett' in ['Garrett Smith', 'Garrett', 'Smith'];

Just in first look, everyone from us know what is a behavior of `in'
operator.
 

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

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top