Security Demands Simplicity (was: Private Slots)

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Jan 21 17:18:48 PST 2013


On Jan 21, 2013, at 4:44 PM, Nathan Wall wrote:

>> Object.create(new Date).getDate(); // works but is specified to not work 
> 
> I understand why this doesn't work, but why *shouldn't* it work? I'm curious why the language doesn't allow for this... ? It seems reasonable at first glance.


Because, the "Dateness" of an object is an characteristic of an instance not of what is on its inheritance  chain. 

In ES <= 5.1 this is defined in terms of the [[Class]] internal property which identifies the specific low level built-in form of an object.  You might think about it as defining the private record structure of an instance and other  specific per instance characteristics such as which internal methods are applicable to the instance.

Changing the prototype (via __proto__) doesn't change the shape of the instance or modify its [[Class]].  That aspect (which at an implementation level, might impact what is actually allocated) is immutably set for each instance when it is allocated.  This is why the built-ins including Array in ES <=5.1 are not "subclassable".

In the the last couple ES6 specs drafts  there is a mechanism  defined in terms of @@create methods that allow subclasses to inherit such specialized instance allocation procedures.  This allows subclasses instance of  Array, Date, and other built-in to be fully functional with all the inherited built-in methods.

An ES programmer could directly invoked Date[@@alloc] like:

let newInst = Date[@@alloc]]();  //allocate a new data-like instance
Date.call(newInst);  //initialize the private date state and make the instance as initalized
newInst.__proto__= Object.create(Date.prototype)  //give it a new prototype that inherits from Data.prototype

but its much easier to just say:

let newInst = new class extends Date{};

which does pretty much the same thing.

Allen



More information about the es-discuss mailing list