-1

I am trying the sort() method with a comapreFunction and I do not understand how the compareNumbers() works. Used with the two variables it returns -3, but when used on an array with the sort method it returns a sorted array. Why does it work like this?

var things = ['Elvis',555,'R2D2'];

function compareNumbers(a, b){
  return a-b;
}
var a = 5;
var b = 8;

console.log(compareNumbers(a,b)); //returns -3
console.log(compareNumbers(things));//returns NaN
console.log(things.sort(compareNumbers(a,b)));//returns a sorted array

What is the logic behind the sort method used with the compareFunction so that it returns a sorted array? Why doesn't it return NaN?

Where can I check what is the code behind a method like library or documentation?

I saw this Understanding sort() compareFunction but it is just overwhelming for me at this stage.

Community
  • 1
  • 1
Henry Lynx
  • 1,099
  • 1
  • 19
  • 41
  • 1
    See http://stackoverflow.com/a/17364128/476. It's for PHP, but the principles are the same and only the implementation syntax differs a little. – deceze Nov 09 '14 at 12:57

2 Answers2

1

compareNumbers(a,b) returns -3 so you are calling things.sort(-3). Since -3 isn't a function it is ignored and the default sort algorithm is used.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • From the specification it seems to me `sort` should throw a `TypeError` when passed -3 instead of a function as argument. But (in Chrome anyway) it doesn't. http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.11 – Stuart Nov 09 '14 at 12:57
  • @Stuart — "If comparefn is not undefined and is not a consistent comparison function for the elements of this array (see below), the behaviour of sort is implementation-defined." – Quentin Nov 09 '14 at 19:53
  • It also says "If IsCallable(comparefn) is false, throw a TypeError exception." – Stuart Nov 09 '14 at 20:13
1

You're calling compareNumbers and passing its return value into sort, which isn't what you want. You want to pass the function into sort, so sort calls it:

console.log(things.sort(compareNumbers));
// No (), no a and b -----------------^

But it's important to note that when either a or b is "Elvis" or "R2D2", your comparator function (compareNumbers) returns NaN, meaning that it's not a "consistent comparison function" according to the specification. This means that whatever sort does at that point is "implementation defined" — totally up to the JavaScript engine's authors, not covered by the specification at all, and likely to vary from one engine to another. sort expects to see a negative number, 0, or a positive number, not NaN. Your things array shouldn't be sorted numerically at all, as two of its entries are not numbers nor can they be correctly converted to numbers.

Here's an example of using a comparator function correctly: In this case, it takes your array and sorts them according to the length of each entry converted to a string:

var things = ['Elvis',555,'R2D2'];

function compareLengths(a, b){
  return String(a).length - String(b).length;
}

snippet.log(things.sort(compareLengths));
<!-- Temporary snippet object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875