extracting namespace from a property

Brendan Eich brendan at mozilla.org
Thu Mar 1 03:07:42 PST 2007


On Mar 1, 2007, at 6:19 AM, Yuh-Ruey Chen wrote:

> 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).

There is code that uses new String, however, so the ToString(this)  
done by each generic method on entry (which results in a string  
primitive) is important.

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

The built-in classes defined in ES3 section 15 are dynamic, but class  
B extends A {} by default is not dynamic. You can have non-dynamic  
subclasses of a dynamic class (necessary since Object is the base  
class of all others and it's dynamic).

IIRC you are allowed to have a dynamic subclass of a non-dynamic  
superclass (Jeff correct me if I'm wrong). dynamic is not inherited,  
and applied to a class, it affects only mutability of instances  
(whether one can add "expandos", i.e. whether the class "seals"  
instances), again if my memory is correct. Others should correct me  
or add more information as needed.

Standard vs. string mode does not change the default for a class that  
lacks an explicit 'dynamic' qualifier.

>> 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.

I've changed the proposal to say that typeof n === "string"; we'll  
see how that flies.

> On the other hand, the |typeof null == 'null'| change is more  
> likely to
> break backwards compat, yet that's currently in ES4.

Concerns about compatibility is giving us pause even for this bug fix  
to make typeof null != 'object' will break anyone who gratuitously  
tests like so:

function isNull(a) {
       return typeof a == 'object' && !a;
}

but I know of now such tests, and spidering various top 1000 web  
sites finds cases that are currently assuming typeof null !=  
'object'. Still the current proposal and spec says we are going to  
attempt this fix, as you note.

> I guess it depends
> on how much you're willing to break.

There's a fine line. If typeof n == 'string' is not helpful, then I  
would prefer to make typeof n == 'object'. Spidering the visible web  
can only produce counter-examples showing how we might help someone  
with an incompatible "bug fix" -- it can't prove that we won't break  
someone else.

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

Yes, string <: String, etc.

/be




More information about the Es4-discuss mailing list