all right, you might think
__proto__
is my obsession but for f*$#k sake not a single engine got it right so far ... and it's perfectly spec'd in ES6 too so I don't know what is with nashorn here ...
// how to fix nashorn Object.defineProperty( Object.prototype, '__proto__', { configurable: true, get: function () { return Object.getPrototypeOf(this); }, set: function (proto) { Object.setPrototypeOf(this, proto); } } );
Are You Asking Why?
Here the answer: nashorn is broken, since it does not expose__proto__
quirks anywhere.'__proto__' in {}
is falseObject.getOwnPropertyNames(Object.prototype).indexOf('__proto__')
is a -1 negativeObject.getOwnPropertyDescriptor(Object.prototype, '__proto__')
is nullBasically even most common basic features detections for
'__proto__'
are screwed, so that not a single library can trust its own code ... how cool is that ...
Broken null
Objects Too
The worst of the worst comes with null
objects, where the infamous property makes dictionaries pointless, not secure, and unreliable ... I start thinking the web world was not even ready for dictionaries, it's taking forever to have a reliable one
var o = Object.create(null); // it's a null object // nothing should affect it o.__proto__ = []; // but nashorn is brilliant // as old Android 2.1 phones here o instanceof Array; // trueCongratulation, you never understood what was the purpose of
__proto__
Quick Specs Recap
So, since it's apparently the first rocket science problem ever, here a quick summary of how stupidly simple is the__proto__
spec:
- if it's a literal expression, not wrapped in quotes, it defines inheritance at runtime:
{__proto__:[]}
which is aninstanceof Array
VS{"__proto__":[]}
which is just valid JSON and won't even affect inheritance - if accessed through the Object.prototype, where whatever object that inherits from
null
should NOT be involved, and where__proto__
has not been defined as own property, it behaves as described in the first snippet I've created to fix nashorn - everything else is an epic fail ... seriously, no difference between
o.__proto__
oro["__proto__"]
and similar madness, if it inherits fromObject.prototype
and the configurable behavior hasn't been deleted it passes through that get/set logic ... that's really it!
</rant>
To be honest, we wanted to get rid of __proto__ altogether and require people to use Object.create, Object.getPrototypeOf() and Object.setPrototypeOf(). Instead we were bullied into supported the deprecated __proto__. I'll submit a bug on your behalf.
ReplyDeletehttps://bugs.openjdk.java.net/browse/JDK-8042364
ReplyDeletethans Jim, as mentioned alredy in the tweet I apolgy for the tone of this post but this property is wrong since ever, disaster prone, and seing this badly implemented in new engines as nashorn is hurts my feeling ... duktape simply respected ES 5.1 specs, as example, and __proto__ indeed is nowhere in there.
ReplyDeleteI don't know who bullied nashorn for this but clearly had no idea what was __proto__ about.
In node.js they use it to extend natives because they have no Object.setPrototypeOf ... no other reasons, really.
Thanks for your understanding and prompt support.
Fixes will make 8u20. The Avatar.js (Node) team will patch the Node sources (locally) to expect the correct behaviour.
ReplyDelete