From: David Mark on
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
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
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
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
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.