Prev: html form in javascript variable
Next: Microsoft and attributes--will they ever figure them out?
From: David Mark on 14 Nov 2009 17:49 On Nov 14, 5:12 pm, Thomas 'PointedEars' Lahn <PointedE...(a)web.de> wrote: [...] > > Of course, that eval() is primarily a method of the ECMAScript Global Object > and that therefore the wrapper is either unnecessary or error-prone, can > already be ascertained by reading the first page of the Netscape/Mozilla.org > Core JavaScript Reference¹, so the person's position in the learning curve > and level of experience must be assessed as being rather early and low. > True, but beside the main point I was trying to illustrate with this (bad) example. This is just as illogical a design:- var GLOBAL = this; var myEval = function(str) { return GLOBAL.eval ? GLOBAL.eval(str) : eval(str); }; ....though a tiny bit closer to competent. I made my example doubly bad. The point is that there is no way this could be counted on to evaluate script with global scope. In short, by design, some percentage of browsers will not be able to - for one - declare global variables. As written, resolving - str - will be an adventure as well.
From: Garrett Smith on 14 Nov 2009 18:19 David Mark wrote: > What is a software engineer? I talked to a group recently and > presented this pattern: > > var myEval = function(str) { > return window.eval ? window.eval(str) : eval(str); > }; > > I know a lot of programmers of various degrees of proficiency read > this group. Can anyone not see the problem with this in the second it > takes to read it? > > Even if you don't know the language, but know that the code must be > executed in various environments (which may or may not feature an eval > method on host objects), logic dictates that this is about as bad as a > design can get (designed to give varying cross-browser results). > Object.prototype.eval was removed from Spidermonkey in 2007, IIRC. I believe that in the case where Object.prototype.eval is implemented (nonstandard), the |this| value is Base object (window here). I never relied Object.prototype.eval, so the quirks of that are not something I attach much value to (worth forgetting). IIRC jquery uses window["eval"] in the source code. looking... hat rack: | // Get the JavaScript object, if JSON is used. | if ( type == "json" ) | data = window["eval"]("(" + data + ")"); Not sure why they chose that approach over: data = eval("(" + data + ")"); That approach uses indirect eval. The calling context's scope is used, so is just as unsafe in that regard. Only difference is older implementations' thisArg is different. It indirect eval, for reasons I'm failing to comprehend. I believe I mentioned this very issue about a year or so ago on the jquery newsgroup. -- Garrett comp.lang.javascript FAQ: http://jibbering.com/faq/
From: David Mark on 14 Nov 2009 18:35 On Nov 14, 6:19 pm, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote: > David Mark wrote: > > What is a software engineer? I talked to a group recently and > > presented this pattern: > > > var myEval = function(str) { > > return window.eval ? window.eval(str) : eval(str); > > }; > > > I know a lot of programmers of various degrees of proficiency read > > this group. Can anyone not see the problem with this in the second it > > takes to read it? > > > Even if you don't know the language, but know that the code must be > > executed in various environments (which may or may not feature an eval > > method on host objects), logic dictates that this is about as bad as a > > design can get (designed to give varying cross-browser results). > > Object.prototype.eval was removed from Spidermonkey in 2007, IIRC. > > I believe that in the case where Object.prototype.eval is implemented > (nonstandard), the |this| value is Base object (window here). > > I never relied Object.prototype.eval, so the quirks of that are not > something I attach much value to (worth forgetting). Definitely. > > IIRC jquery uses window["eval"] in the source code. looking... > > hat rack: > | // Get the JavaScript object, if JSON is used. > | if ( type == "json" ) > | data = window["eval"]("(" + data + ")"); > > Not sure why they chose that approach over: > data = eval("(" + data + ")"); Voodoo.
From: Richard Cornford on 14 Nov 2009 22:17 Thomas 'PointedEars' Lahn wrote: > David Mark wrote: <snip> >> How about this one:- >> >> if (typeof xyz == 'array' || xyz instanceof Array) { >> ... >> } >> >> First test is _never_ true in an ECMAScript implementation. > > That is not quite correct. The first test could result in `true' > in a conforming implementation of ECMAScript if `xyz' referred to > a host object. But I doubt the person writing it was aware of > that or even intended to meet the case. <snip> That "could result in 'true'" is very much a theoretical possibility; a host object may result in any string when - typeof - is applied to it, but it is extremely rare that they do result in anything that is not already in the ECMAScript list, and the exception ('unknown' in IE when testing ActiveX objects, methods and properties) is literally the only one that I have ever encountered, or heard tell off. Personally, I don't believe that there has ever been a browser environment in which any object (host or otherwise) resulted in 'array' when - typeof - was applied to it. I think that is formulation (and the many similar - typeof - tests) is just another of those mystical inactions that start out as someone's mistake and propagate precisely because they are essentially harmless (the 'array' result never happens and so the code guarded by it is either unconditionally executed or not executed). That is probably the measure of an 'engineer' in this context; an engineer would want to identify and eliminate the mystical incantations from what they were doing. Richard.
From: Richard Cornford on 14 Nov 2009 22:39
Garrett Smith wrote: <snip> > IIRC jquery uses window["eval"] in the source code. looking... > > hat rack: > | // Get the JavaScript object, if JSON is used. > | if ( type == "json" ) > | data = window["eval"]("(" + data + ")"); > > Not sure why they chose that approach over: > data = eval("(" + data + ")"); > > That approach uses indirect eval. The calling context's scope is > used, so is just as unsafe in that regard. Only difference is older > implementations' thisArg is different. > > It indirect eval, for reasons I'm failing to comprehend. > > I believe I mentioned this very issue about a year or so ago on > the jquery newsgroup. I have a recollection of discussions around the use of - eval - relating the 'compressors' (YUI compressor, as I recall) that modify (shorten) Identifier names. Much like the way such a compressor cannot act on code within a - with - statement because there is no means of determining whether an unqualified Identifier in that context is a name of a property of the object added to the scope chain or a reference to a variable/function/parameter from a containing scope, such compressors cannot act on unqualified Identifiers in the lexically containing scopes when - eval - is used, because it has no way of determining whether any string that is - eval-ed will attempt to use them to refer to items from those containing scopes. My impression was JQuery's authors were then going to do whatever was necessary to fool the compressor in question into not noticing the - eval - use (and making it unrecognisably indirect should achieve that). Obviously the sane alternative, of using - new Function - to create a minimal scope chain function that wrapped the (now not indirect) eval call, did not occur to them. Richard. |