From: David Mark on
Michael Haufe ("TNO") wrote:
> On Mar 1, 11:34 pm, David Mark <dmark.cins...(a)gmail.com> wrote:
>
>> "Expected an identifier and instead saw 'undefined' (a reserved word)."
>> - In jQuery we re-declare 'undefined' as we use it internally. Doing so
>> prevents users from accidentally munging the name (assigning to
>> undefined and messing up our tests) and also makes the undefined checks
>> slightly faster."
>>
>> Messing up their tests?! And I fail to see how using a variable makes
>> checking for an undefined variable any faster.
>
> I would expect it to be significantly faster and more correct if they
> used "void 0" instead of a name of any sort for this.

Or a typeof test.

> Of course, no
> one there reads this list by their own admission... So I wouldn't be
> surprised to see this exact change shows up in their code base soon ;).

Yes, it would be another in a long series of "coincidences." Of course,
the changes usually show up (much) later rather than sooner.

But their marketers continue to steer the users clear of this newsgroup
as they want them to think that the jQuery geniuses can get along just
fine on their own. The most inexplicable (on a number of levels)
comment I saw recently was that they should look to the JS "experts"
that frequent sites like StackOverflow and (groan) the Dojo mailing list
(no that's not a misprint).

The most ironic part of that is that the typical jQuery zealot hates me
when they should be thanking me for making their lives (a little)
easier. I guess it doesn't help that my primary proxy reinforces the
perception my "unhelpful" nature at every turn (focusing on the contrast
to his "helpful" parroting of my ideas). Crazy world.
From: Garrett Smith on
David Mark wrote:
> lorlarz wrote:
>> On Mar 1, 6:56 pm, Stefan Weiss <krewech...(a)gmail.com> wrote:
>>> On 02/03/10 01:32, lorlarz wrote:
>>>
[...]

> "We ignore the following warnings from JSLint:
>
> "Expected an identifier and instead saw 'undefined' (a reserved word)."

That JSLint Error is completely wrong. `undefined` is a property of the
global object, not a reserved word. It is not an error and should not be
flagged as an error.

[...]

>
> Messing up their tests?! And I fail to see how using a variable makes
> checking for an undefined variable any faster.

We discussed this last year, IIRC.

Think about how scope chain and identifier resolution works. `undefined`
is an identifier, not a reserved word, so it must be resolved up the
scope chain, just like any other identifier.

The short answer to why it should faster is that the identifier
`undefined` is resolved sooner on the scope chain, rather than looking
up to the global scope.

[...]

>
> Evil is right. IIRC, they never did figure out that the Function
> constructor is more appropriate for that task.
>

The function constructor is safer because it does not use global scope.

// Use grouping operator to avoid ASI-related error.
var f = new Function("return("+responseText");");

// later on.
var responseValue = f();

> ""forin" - This removes the requirement of doing a hasOwnProperty check
> inside of for/in loops. jQuery doesn't support working in an environment
> that has manipulated the Object.prototype as it's considered harmful."
>
> Yes, harmful to incompetently written scripts. ;)
>

Exactly, IIRC Prototype JS 1.5 or so was modifying Object.prototype.
They probably got the idea from Crockford, who, actually advocated doing
that and called scripts that didn't handle it "incompetent".

> The style guide continues:-
>
> "TYPE CHECKS
>
> String: typeof object === "string"
> Number: typeof object === "number"
> Boolean: typeof object === "boolean"
> Object: typeof object === "object""
>
> Cargo cult. There's no reason to use strict comparisons here.
>

It doesn't really matter either way. It is marginally faster, but
insignificantly so.

The rule I have tried to be consistent with is to use === unless == is
needed, which is pretty rarely.

I chose this because the person reading the code might wonder there is
== in one string comparison check and === in another. If === is used for
other comparisons of string values, then it can be used consistently
without ambiguity or confusion.

> "Function: jQuery.isFunction(object)"
>
> typeof fn == 'function'; // Don't ever use such tests with host objects
>
> "Array: jQuery.isArray(object)"
>
> I'm sure that's the less-than-solid "Miller Device" (another device that
> should be designed out of the system, but can't be at this late date).
>

My favorite one is Dojo `it instanceof Array || typeof it == "array"`.
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
From: Garrett Smith on
Stefan Weiss wrote:
> On 02/03/10 04:57, lorlarz wrote:
>> ** BIG UPDATE **:
>> jQuery now passes JSLint 100% but with noted exceptions:

[...]

> | * "Expected an assignment or function call and instead saw an
> | expression." - There are two areas in which we access a property with
> | seemingly no side effect, those are:
> |
> | o parent.selectedIndex; (or similar) this is due to the fact that
> | WebKit mis-reports the default selected property of an option,
> | accessing the parent's selectedIndex property fixes it.
>

The workaround is an undocumented quirk.

> David mentioned there was a better way to work around this, but I'm not
> sure what he was referring to.
>

Probably to give the OPTION the `selected` attribute, as RobG pointed
out last year.

Anyhow, it is resolved by following advice in the HTML specification
from a decade ago:

| "Since user agent behavior differs, authors should ensure that each
| [select] includes a default pre-selected OPTION."
|
| <URL: http://www.w3.org/TR/html4/interact/forms.html#h-17.6.1 >

http://groups.google.com/group/comp.lang.javascript/msg/93c61c9ad6e2210c?dmode=source

[...]
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
From: David Mark on
Garrett Smith wrote:
> David Mark wrote:
>> lorlarz wrote:
>>> On Mar 1, 6:56 pm, Stefan Weiss <krewech...(a)gmail.com> wrote:
>>>> On 02/03/10 01:32, lorlarz wrote:
>>>>
> [...]
>
>> "We ignore the following warnings from JSLint:
>>
>> "Expected an identifier and instead saw 'undefined' (a reserved word)."
>
> That JSLint Error is completely wrong. `undefined` is a property of the
> global object, not a reserved word. It is not an error and should not be
> flagged as an error.

But using it as an argument name is pretty stupid.

>
> [...]
>
>>
>> Messing up their tests?! And I fail to see how using a variable makes
>> checking for an undefined variable any faster.
>
> We discussed this last year, IIRC.
>
> Think about how scope chain and identifier resolution works. `undefined`
> is an identifier, not a reserved word, so it must be resolved up the
> scope chain, just like any other identifier.

And therein lies my mistake. I know how identifier resolution works (my
whole library is based on avoiding global resolution), but the previous
warning caused a brain malfunction as to the undefined identifier.
Personally I prefer the typeof test. If space is a concern, set a local
variable to the string "undefined" and compare to that, but then that
will be slower than comparing to a string literal.

>
> The short answer to why it should faster is that the identifier
> `undefined` is resolved sooner on the scope chain, rather than looking
> up to the global scope.

Assuming implementations don't optimize for the undefined identifier in
some way.

>
> [...]
>
>>
>> Evil is right. IIRC, they never did figure out that the Function
>> constructor is more appropriate for that task.
>>
>
> The function constructor is safer because it does not use global scope.

I assume you meant that it does use the global scope, whereas eval uses
whatever scope the call resides in.

>
> // Use grouping operator to avoid ASI-related error.

Huh?

> var f = new Function("return("+responseText");");
>
> // later on.
> var responseValue = f();
>
>> ""forin" - This removes the requirement of doing a hasOwnProperty check
>> inside of for/in loops. jQuery doesn't support working in an environment
>> that has manipulated the Object.prototype as it's considered harmful."
>>
>> Yes, harmful to incompetently written scripts. ;)
>>
>
> Exactly, IIRC Prototype JS 1.5 or so was modifying Object.prototype.
> They probably got the idea from Crockford, who, actually advocated doing
> that and called scripts that didn't handle it "incompetent".

And round and round it goes. Regardless, it doesn't make sense to use
unfiltered for-in loops on the Web.

>
>> The style guide continues:-
>>
>> "TYPE CHECKS
>>
>> String: typeof object === "string"
>> Number: typeof object === "number"
>> Boolean: typeof object === "boolean"
>> Object: typeof object === "object""
>>
>> Cargo cult. There's no reason to use strict comparisons here.
>>
>
> It doesn't really matter either way. It is marginally faster, but
> insignificantly so.

I would think that would depend on the implementation. But it is
interesting that they would take the size hit of an extra character for
no reason (they seem to count characters fanatically).

>
> The rule I have tried to be consistent with is to use === unless == is
> needed, which is pretty rarely.

I do the exact opposite. Why use strict if you don't have to?
Regardless of possible minute performance benefits, I think it obscures
the meaning of the code (when I see strict comparisons, I figure there
is a good reason for them).

>
> I chose this because the person reading the code might wonder there is
> == in one string comparison check and === in another. If === is used for
> other comparisons of string values, then it can be used consistently
> without ambiguity or confusion.

I like it better my way. :)

>
>> "Function: jQuery.isFunction(object)"
>>
>> typeof fn == 'function'; // Don't ever use such tests with host objects
>>
>> "Array: jQuery.isArray(object)"
>>
>> I'm sure that's the less-than-solid "Miller Device" (another device that
>> should be designed out of the system, but can't be at this late date).
>>
>
> My favorite one is Dojo `it instanceof Array || typeof it == "array"`.

Buffoons. I tried to tell them that was ridiculous, but they just
carped about providing "proof" (and something about ad hominem attacks).
That was the end of that. Now here they are getting ridiculed (again).
I can't bring myself to feel sorry for them. Maybe they enjoy being
laughingstocks, but they do seem put off by the fact that nobody is
using their "great" library. Nothing about that group adds up.

I kept trying to tell them that if they argue over every miserable
mistake, it was going to take forever to get through all of the code.
Near as I can tell, they are still stuck on the very first major problem
(their "global" eval method). And they can't claim I was unhelpful as I
personally rewrote the bulk of it for them (which they almost
immediately dismissed as not theirs). :)
From: David Mark on
Garrett Smith wrote:
> Stefan Weiss wrote:
>> On 02/03/10 04:57, lorlarz wrote:
>>> ** BIG UPDATE **:
>>> jQuery now passes JSLint 100% but with noted exceptions:
>
> [...]
>
>> | * "Expected an assignment or function call and instead saw an
>> | expression." - There are two areas in which we access a property with
>> | seemingly no side effect, those are:
>> |
>> | o parent.selectedIndex; (or similar) this is due to the fact that
>> | WebKit mis-reports the default selected property of an option,
>> | accessing the parent's selectedIndex property fixes it.
>>
>
> The workaround is an undocumented quirk.

Yes, they are big on those. Seeing something happen in a browser is all
the "proof" they need to treat it as a viable solution. Dojo does this
constantly too. Wonder why these things have to be constantly rewritten
to keep up with three or four browsers?

>
>> David mentioned there was a better way to work around this, but I'm not
>> sure what he was referring to.
>>
>
> Probably to give the OPTION the `selected` attribute, as RobG pointed
> out last year.

No probably about it (though it sets the property, not the attribute).
It was discussed to death (here and in jQuery-land). Everyone knows
what it is supposed to do, but nobody (sane) would do it that way.