instanceof Operator

Brendan Eich brendan at
Sun Oct 21 12:20:08 PDT 2007

On Oct 21, 2007, at 11:48 AM, Jeff Dyer wrote:

>> The wrapper classes String, Number, Boolean are similar to the
>> (primitive) values they wrap, but they're not really related to those
>> value types in a type sense, and in ES4 the wrappers are of even less
>> utility than in ES3, I would say.
> Right, thanks for the correction. This is an obvious consequence of  
> the
> recent return of primitive wrappers to ES4. 'string' is the new  
> 'String'!

String has its uses, not just embedded in content that requires  
compatibility: string and String inter-convert, String is non-final,  
and the two share a prototype object.

The need for string comes directly from ES1-3, because the primitive  
string type in JS1 was auto-wrapped when you used a string value as  
if it were an object, say to call a method on it. But since a new  
wrapper was created each time (or so it appeared; implementations  
could optimize), the object-ness of the primitive string was  
ephemeral: you couldn't set methods and get them later; any get on  
the wrapper for a property not found on String.prototype or above  
would return undefined.

In ES4, string has catchalls to satisfy this ephemeral wrapper get/ 
set compatibility, but method calls on string instances do not  
require String wrapper creation.

Wrapper creation may or may not be observable in ES3 -- 9.9 says  
"create a new String" but does not say by evaluating |String| in  
order to construct -- but ES4 does not allow any type name to be re- 
bound, so the implementations that chose to construct the wrapper by  
reflecting on the current value of 'String' in the global object,  
thereby allowing someone to replace that binding and spy on wrapper  
construction, no longer need to reflect each time.

The shared prototype object allows for replacement of prototype  
methods, which per ES1-3 and much compatibility-constraining content  
on the web, remain mutably bound in the shared prototype object. Thus  
in ES1-3, if you wrapped String.prototype.charAt with some AOP advice  
function, your code calling "hi".charAt(0) will still run your advice.

Since ("hi instanceof String) was never true, it should not be true  
in the new world. This is one reason string and String are peer  
subtypes of Object, that is, string is not a subtype of String.

Tucker and others have hoped for a way to customize String, and since  
it is non-final and convertible to string, the use-cases that want to  
make custom objects that delegate to String.prototype should work  
too. But it would be good to see some examples.


More information about the Es4-discuss mailing list