ES3.1 Object static methods rationale document
Allen Wirfs-Brock
Allen.Wirfs-Brock at microsoft.com
Wed Jul 16 08:28:56 PDT 2008
I didn't specifically respond to that thread because I wasn't aware of it. I had intended to mention __proto__ as a precedent but it slipped through the cracks.
It's true that __proto__ or getPrototypeOf breaks an object's encapsulation barrier and reveals implementation details that perhaps were intended to be hidden. The same could be said about the proposed getProperty function which, among other things, gives an observer access to the functions that implement a getter/setter property. In general, that's the nature of reflection. Overall, I think that this is a situation that is inherent in our current generation of dynamic languages. They tend to depend upon the use of idioms that require penetration of the encapsulation barrier.
Some of the concerns expressed in that thread are address by other aspects of the static Object methods proposal. For example, the integrity of prototype objects can be protected by sealing them in whole or in part to prevent tampering. Also note, that while we support inspection of the prototype value, we don't support modification of it.
As Doug implies below, one reason for making these operations "static methods" was to make it easier to control access to them. It you are creating some sort of sandbox, you may not want to make them available within it. That could be taken as a argument in favor of hanging them off of a dedicated global Meta object rather than off of Object. It may be slightly easier to wholesale restrict access to Meta than it would be to restrict access to just these methods while still providing access to the Object constructor.
Another already available technique for obtaining the same information in many situations that wasn't mentioned in the thread is to use Object.prototype.isPropertyOf as a probe to discover the prototypes of objects. It isn't something that you would want to do in production code but I don't think that anyone who was trying to crack an application would hesitate from doing.
Arguably, some of the need for direct prototype access is alleviated by providing the clone method. However, there are still plenty of other situations where it is useful.
I don't agree with Lars' contention that __proto__ and function.caller present the same kind of problem. True, they both break abstraction barriers, but different barriers. __proto__ breaks the object implementation abstraction layer. Function.caller breaks the call stack abstraction. Crossing the object implementation boundary is generally required for defining object abstractions in this language and __proto__ only reveals information that in most cases is already available through other, less direct, means. In contrast, function.caller reveals information about the call stack that is not normally reified in this language or generally needed (those who consider continuations the ultimate programming abstraction may disagree).
In summary, not providing reflective access to an object's prototype doesn't really provide any real security, it just makes some useful tasks less convenient. Reverting to barnyard analogies: the barn door is already wide open and we're debating an inch wide "trench" that spans the opening. If we want to keep the horses in we need to think about how to put an iron gate across that gap rather than worrying about the risks of filling in the trench.
Allen
-----Original Message-----
From: Douglas Crockford [mailto:douglas at crockford.com]
Sent: Wednesday, July 16, 2008 5:39 AM
To: Brendan Eich
Cc: Allen Wirfs-Brock; es3.x-discuss at mozilla.org; es4-discuss at mozilla.org
Subject: Re: ES3.1 Object static methods rationale document
Brendan Eich wrote:
> * No rationale responding to the thread containing this message:
>
> https://mail.mozilla.org/pipermail/es4-discuss/2007-September/001114.html
>
> that questions the wisdom of getPrototypeOf. The other rationales are
> helpful, the lack of one responding to this public thread questioning
> essentially the same design element is a lack -- what do you think?
The motivation for these methods is to allow Ajax libraries and the Caja runtime
to harden the environment. Such a library can use and them remove these methods,
disallowing access by guest code.
> * Did you consider prototype's Object.extend method:
>
> Object.extend = function(destination, source) {
> for (var property in source)
> destination[property] = source[property];
> return destination;
> };
Yes we did.
More information about the Es4-discuss
mailing list