__proto__
Lars T Hansen
lth at acm.org
Tue Sep 11 04:36:18 PDT 2007
On 9/11/07, liorean <liorean at gmail.com> wrote:
> On 11/09/2007, Lars T Hansen <lth at acm.org> wrote:
> > On the one hand, __proto__ is another potential security hole, and it
> > prevents implementations from sharing prototype objects among multiple
> > documents -- the link may be read-only but the object isn't. Function
> > B called from function A with object O may hack O.__proto__ and A can
> > do nothing about it; suddenly all O-like objects in the system act
> > differently.
> >
> > On the other hand, Constructor.prototype is generally available for
> > any Constructor, so it's hard to see what the real damage is -- it's
> > not obviously worse than some other aspects of the language.
>
> For ES3 code, exposing __proto__ means that prototypes on constructors
> protected by scope (as is becoming practice by at least library
> writers today) are exposed, which they weren't before.
OK, that's the problem I was alluding to in my "on the third hand".
> It also means
> that a prototype that is thrown away after setting up the object will
> now be accessible.
That I don't get. The object is the prototype object of some other
object, the garbage collector can't collect the proto until the
referencing object can be collected. It's pretty clear to me that you
can't fold the prototype into the object itself without a lot of extra
machinery. Perhaps you can provide a concrete example?
> > On the third hand, some implementations may have specialized objects
> > for which no Constructor is available and for whom keeping
> > [[Prototype]] unavailable is desirable. Similarly, some toolkits may
> > have private prototype objects that are not available to client code
> > because the constructor is hidden in a lexical scope (ES3) or
> > package/namespace (ES4).
> >
> > Introspection is great, but it assumes a lot about how trust works in
> > the environment.
>
> Hmm. On another note: Would it be reasonable to standardise a way to
> attach a prototype chain to a plain object instanciator? (Instead of
> reading one out of an object...)
>
>
> var
> someObject={
> mySharedValue: value},
> someOtherObject={
> "[[prototype]]": someObject};
>
> This would get rid of the need for a function call (Crockford's object
> function for instance) for setting up plain ES3 prototypal
> inheritance, and would mean some structures that are not currently
> serialisable as JSON despite being plain value structures would become
> serialisable.
I can't argue about the serialization bit.
I love to argue about performance, though, so I'll take your "get rid
of the need for a function call" as an argument about performance and
proceed from there :)
If function calls are so expensive that they dominate object creation
time we should worry about how we can make them faster, I think,
especially if the language gets in the way of good performance. It's
true function calls are a little heavyweight in ES...
A quick test comparing 0-argument function calls to allocation of
empty objects using {} syntax follows. Results are reported as the
number of calls that can be made in the time it takes to perform one
allocation.
On a MacBook Pro:
calls per alloc
Opera 9.5a1 3.48
Opera 9.2 0.66
Safari 2 0.68
On a Thinkpad T60p:
FF 2.0.0.6 2.88
IE 6 1.27 (at 1/10 the number of iterations
because of the silly "slow script" dialog)
This probably includes a little GC time for the allocation test but
that doesn't seem unfair. Test code included below.
This simplistic test indicates that some browsers (Opera 9.2, Safari
2) have particularly slow calls relative to allocations and so your
concern may well be warranted. But if Safari 3 and to a lesser extent
IE 7 perform better, the overhead of a call may not be much to worry
about.
Obviously the test completely ignores the fact that, say, calls in
Safari may be much faster than in another browser, it may just be that
the allocator is superfast too, at which point the ratio is not very
relevant. (That does not seem to be the case, though. The browsers
are all pretty much comparable. The big change for Opera is explained
by allocation running at half the speed in 9.5 while calls are much
faster.)
--lars
function g() {}
function testalloc() {
var x;
for ( var i=0 ; i < 1000000 ; i++ ) {
x = {};
}
}
function testcall() {
var x;
for ( var i=0 ; i < 1000000 ; i++ ) {
g();
}
}
var t1 = new Date;
testalloc();
var t2 = new Date;
testcall();
var t3 = new Date;
document.writeln("Calls per alloc = " + 1/((t3 - t2)/(t2 - t1)));
> --
> David "liorean" Andersson
> _______________________________________________
> Es4-discuss mailing list
> Es4-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es4-discuss
>
More information about the Es4-discuss
mailing list