views:

130

answers:

1

While debugging a javascript code that uses jQuery I found the following code:

[0, 0].sort(function()
{
    baseHasDuplicate = false;
    return 0;
});

By my understanding of javascript this code will sort array containing two zeroes with comparison function that will always set a global variable and will return equality, which has same effect as baseHasDuplicate = false;.
Coming from a valued source I think I missed something. Did I miss something or is this a programming fail?

+9  A: 

As you can see here (chinese), this code might be used to test for Chrome. EDIT: see below for the complete story..

As explained in the article, what happens is that Chrome optimizes the ".sort(...)" method in such a way that the [0, 0].sort(...) call won't execute the given comparison function.

From the article, Chrome's implementation of ".sort(...)" is something like:

function sort(comparefn) {
  var custom_compare = (typeof(comparefn) === 'function');
  function Compare(x,y) {
    if (x === y) return 0;
    if (custom_compare) {
      return comparefn.call(null, x, y);
    }
    ...
}

As 0 === 0 is true, it won't call comparefn.

In the case of jQuery, it won't set the global variable baseHasDuplicate to false.


EDIT: if you browse Sizzle's source code, here for example (go to the yellow section under "Sizzle CSS Selector Engine", called "Sizzle variables"), you will find the following explanation:

var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
        done = 0,
        toString = Object.prototype.toString,
        hasDuplicate = false,
        baseHasDuplicate = true;

// Here we check if the JavaScript engine is using some sort of
// optimization where it does not always call our comparision
// function. If that is the case, discard the hasDuplicate value.
//   Thus far that includes Google Chrome.
[0, 0].sort(function(){
        baseHasDuplicate = false;
        return 0;
});     

Looks demystified!

Bruno Reis
thats a bit harsh considering there is easy methods to check that
Dani
oh, there are programming fails everywhere. sometimes people really like the bad way of doing things :)
Jimmie Lin
@Dani: indeed! However, the code might be used for something else... It would be great to hear from "the Javascript Ninja".
Bruno Reis
I don't get it... what does hasDuplicate do?
Dani
@Dani: well, that's another question! It will be used (in "Sizzle.uniqueSort(...)") to check if the browser is calling the sort function as needed by Sizzle.
Bruno Reis
@Dani - `hasDuplicate` is used by `Sizzle.uniqueSort()` to determine if there are duplicates that can be removed from the passed-in array, but I'm still trying to figure out why the way they handled this makes the most sense (the value of `hasDuplicate` is normally set by the custom comparison function, and cannot be relied on if the need to call the custom comparison function has been optimized away).
Tim Stone
what does it matter if its called or not? its a damn sort
Dani
@Dani - Oh, whoops. I understand the code now, I was thinking about it backwards. If the function *isn't* optimized away, `baseHasDuplicate` is false, allowing the custom comparison function to determine if there are duplicates. If it *has* been optimized away, this ensures `hasDuplicate` is always `true`, meaning the traversal of the array to remove duplicates will always occur (essentially a counter-optimization to Chrome's optimization of `sort()`).
Tim Stone
This is not an optimization. the algorithm will take O(n log n) or O(n^2) in some browsers and the O(n) of duplicate removal will change nothing. If they really wanted to optimize they could write their own sorter that deletes duplicates while sorting(will add O(log n) loop instead of O(n)).
Dani
@Dani - Well, it is in the context of how they've chosen to do it, but you're certainly right that it's largely irrelevant if the overall approach is wasteful. You'd have to ask the code's author why they chose to do it that way, since I see no apparent reason why they couldn't have written a custom sorter to remove duplicates in-process as you've suggested.
Tim Stone
Considering that the sorter of some browsers is highly unoptimized with some browsers(safari for instance) with best cast of O(n^2)
Dani