Doesn't Object.keys() solve this problem? jjb
On Wed, Dec 28, 2011 at 1:09 AM, Axel Rauschmayer <[email protected]> wrote: > The cleanest solution to the problem you outlined seems to be to never use > objects as dictionaries(?) That is, one would separate the concerns program > definition and application data. Allen’s object model reformation (allowing > one to override the [] operator) would help, too. > http://wiki.ecmascript.org/doku.php?id=strawman:object_model_reformation > > > On Dec 27, 2011, at 3:53 , Mark S. Miller wrote: > > Or, "Even Crock's Code Doesn't Overcome All The Bad Parts." > > > In this message, I explain why I believe we need to clean up __proto__. > I'll start a separate thread on how to clean it up -- which is just my > documenting a suggestion from Dave Herman. > > > From < > http://eleventyone.done.hu/OReilly.JavaScript.The.Good.Parts.May.2008.pdf> > PDF page 119 > > that.on = function (type, ....) { > .... > var registry = {}; > .... > if (registry.hasOwnProperty(type)) { > registry[type].push(handler); > } else { > registry[type] = [handler]; > } > .... > }; > > This "registry" is a classic use of an object as a string-to-value > map. Note that the "type" parameter comes in from the client of the > abstraction. The only validation performed on it is the "hasOwnProperty" > check above. Elsewhere Crock points out that this hasOwnProperty check does > not work if "hasOwnProperty" itself is ever used as a key, and so we should > instead say: > > if (Object.prototype.hasOwnProperty.call(registry, type)) { > > This still doesn't yet work on most actual browsers for a reason explained > below. > > > > <aside on why ES5 does not really help> > > Going beyond "Good Parts", EcmaScript 5 gives us two new opportunities to > clean up this code further. > > 1) We can protect ourselves from other code monkey patching > away Object.prototype.hasOwnProperty > and/or Object.prototype.hasOwnProperty.call by using < > http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming> > at initialization time, assuming that this module gets to initialize itself > before such monkey patching may have occurred: > > var bind = Function.prototype.bind; > var uncurryThis = bind.bind(bind.call); > > var hopFn = uncurryThis({}.hasOwnProperty); > > So that we can say > > if (hopFn(registry, type)) { > > 2) We can replace the initialization of "registry" with > > var registry = Object.create(null); > > or, if we wish the same protection from post-initialization monkey patching > > var create = Object.create; > ... > var registry = create(null); > > It turns out that neither of these additional ES5-based paranoid steps > helps with the worst problem remaining with Crock's corrected code. > Likewise, nothing so far proposed for ES-next would help, except for Dave > Herman's suggestion which I will write up shortly. > > </aside on why ES5 does not really help> > > > > As you've probably already guessed from the title of this email, the > problem occurs on most platforms when the function is called with an > argument of "__proto__". Since we do a "hasOwnProperty" check first, the > way in which this goes wrong depends on the platform. Evaluating > > [{}.hasOwnProperty('__proto__'), > {}.__proto__.hasOwnProperty('__proto__')] > > on various browsers gives: > > false,false // Chrome > true,true // WebKit Nightly > false,true // FF Nightly > false,false // Opera 12 alpha > throws TypeError // IE10 Preview 2 > > Since IE doesn't treat "__proto__" as special magic, no problem there. > WebKit Nightly will take the branch that happens to fail safe here, but > only for the reason that there's no "Object.prototype.push". All we can say > is that we got lucky this time. When Chrome, FF, and Opera evaluate > > registry['__proto__'] = [handler]; > > they change registry to inherit from [handler] rather than > Object.prototype. WebKit would do the same if it had executed this line. > > Think this exercise is academic and doesn't arise in real systems? As > observed at < > http://www.google.com/support/forum/p/Google+Docs/thread?tid=0cd4a00bd4aef9e4>, > until recently, on all non-IE browsers, if you typed "__proto__" at the > beginning of a new Google Doc, your Google Doc would hang. This was tracked > down to such a buggy use of an object as a string map. (To avoid such > problems, Caja is shifting to using < > http://code.google.com/p/es-lab/source/browse/trunk/src/ses/StringMap.js>, > which does seem safe on all platforms.) > > > -- > Cheers, > --MarkM > _______________________________________________ > es-discuss mailing list > [email protected] > https://mail.mozilla.org/listinfo/es-discuss > > > -- > Dr. Axel Rauschmayer > [email protected] > > home: rauschma.de > twitter: twitter.com/rauschma > blog: 2ality.com > > > > > _______________________________________________ > es-discuss mailing list > [email protected] > https://mail.mozilla.org/listinfo/es-discuss > >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

