extracting namespace from a property

Yuh-Ruey Chen maian330 at gmail.com
Thu Mar 1 05:19:19 PST 2007


Brendan Eich wrote:
> > Well as I mentioned, although Name would derive from String, it would
> > still have to redefine all of String's methods.
>
> Not so -- see ES1-3, where String.prototype methods except for  
> toString and valueOf are intentionally generic. They convert their  
> this parameter ToString and then operate on the result of that  
> internal type conversion call.
>
> > This implies that any
> > method added to String's prototype would not automatically work with a
> > Name instance. Unless the way Name delegates String methods via some
> > __noSuchMethod__/__resolve__ hook.
>
> Generic methods on String.prototype automatically work, where "work"  
> is defined as operate on ToString(n), without hassle. If one adds a  
> specific String.prototype method that can't cope with Name, but  
> operates on its |this| parameter only if that parameter is exactly a  
> string instance already, then it will throw when called on Name --  
> which will tell the programmer to extend Name.prototype too (if we do  
> decide to make class Name be dynamic).
>   

Ah, I totally forgot about string methods being generic (AFAIK there's
practically no code out there that has a constructor whose prototype is
String or has a String method as a property of a non-String object).

In standard mode, every class (except maybe host objects) are dynamic,
right? Or at least would every builtin class is dynamic in standard mode?

> >> Given Name <: String, it makes sense for (typeof n === "string")
> >> given (n is Name).
> >>
> >
> > Does this mean that in ES4 typeof Object(string) == "string"  
> > instead of
> > "object" (and for other primitive wrappers)?
>
> That would have been the case if we had managed to merge string  
> primitive type with String object wrapper, but we can't, so what  
> happens instead is the same as today:
>
> js> typeof Object('hi')
> object
> js> Object('hi') instanceof String
> true
>
> > Since Name instances are
> > objects, typeof name should be "object", unless objects and their
> > primitive counterparts have been unified with respect to typeof.
>
> typeof new Name('hi') === "object", as you would expect.
>
> We can't merge string and String, etc.
>
> /be
>   

Hmm...that will be troublesome in the case where a key is passed to a
function that tries to check if the passed argument is a string only via
typeof:

function foo(x) {
    if (typeof x == 'string') {
       // if x is a Name, we won't get here
    }
}

for (k in o) foo(k);

Of course, the function should have |x instanceof String|. But if the
program was designed so that it guaranteed that it never passed String
objects to foo, and foo is passed keys within a for-in loop, and that
for-in loop was iterating over an object containing a qualified
property, we run into backwards compatibility trouble.

On the other hand, the |typeof null == 'null'| change is more likely to
break backwards compat, yet that's currently in ES4. I guess it depends
on how much you're willing to break.

New ES4 code would typically use the |is| operator anyway, and
primitives and wrappers are unified under |is|, right?

-Yuh-Ruey



More information about the Es4-discuss mailing list