Prev: FAQ Entry Proposal: What is (function(){ /*...*/ })() ?
Next: FAQ Topic - What is Ajax? (2010-03-01)
From: David Mark on 2 Mar 2010 01:16 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 2 Mar 2010 02:50 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 2 Mar 2010 03:08 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 2 Mar 2010 03:22 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 2 Mar 2010 03:27
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. |