You can also create a dynamic sort function that sorts objects by their value that you pass:
function dynamicSort(property) {
var sortOrder = 1;
if(property[0] === "-") {
sortOrder = -1;
property = property.substr(1);
}
return function (a,b) {
var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
return result * sortOrder;
}
}
So you can have an array of objects like this:
var People = [
{Name: "Name", Surname: "Surname"},
{Name:"AAA", Surname:"ZZZ"},
{Name: "Name", Surname: "AAA"}
];
...and it will work when you do:
People.sort(dynamicSort("Name"));
People.sort(dynamicSort("Surname"));
People.sort(dynamicSort("-Surname"));
Multiple Parameters
You can use the function below to generate sort functions with multiple sort parameters.
function dynamicSortMultiple() {
/*
* save the arguments object as it will be overwritten
* note that arguments object is an array-like object
* consisting of the names of the properties to sort by
*/
var props = arguments;
return function (obj1, obj2) {
var i = 0, result = 0, numberOfProperties = props.length;
/* try getting a different result from 0 (equal)
* as long as we have extra properties to compare
*/
while(result === 0 && i < numberOfProperties) {
result = dynamicSort(props[i])(obj1, obj2);
i++;
}
return result;
}
}
Which would enable you to do something like this:
People.sort(dynamicSortMultiple("Name", "-Surname"));
Adding It To The Prototype
(Implementation which is just below is inspired from Mike R's answer)
I wouldn't recommend changing a native object prototype but just to give an example so you can implement it on your own objects (For the environments that support it, you can also use Object.defineProperty as shown in the next section, which doesn't have the negative side-effects of fiddling with a native object's prototype, as described at the last part)
Prototype implementation would be something like the following (Here's a working example):
//Don't just copy-paste this code. You will break the "for-in" loops
!function() {
function _dynamicSortMultiple(attr) {
/* dynamicSortMultiple function body comes here */
}
function _dynamicSort(property) {
/* dynamicSort function body comes here */
}
Array.prototype.sortBy = function() {
return this.sort(_dynamicSortMultiple.apply(null, arguments));
}
}();
The Proper Way Of Adding It To The Prototype
If you're targeting IE v9.0 and up then, as I previously mentioned, use Object.defineProperty like this (working example):
//Won't work below IE9, but totally safe otherwise
!function() {
function _dynamicSortMultiple(attr) {
/* dynamicSortMultiple function body comes here */
}
function _dynamicSort(property) {
/* dynamicSort function body comes here */
}
Object.defineProperty(Array.prototype, "sortBy", {
enumerable: false,
writable: true,
value: function() {
return this.sort(_dynamicSortMultiple.apply(null, arguments));
}
});
}();
All those prototype fun enables this:
People.sortBy("Name", "-Surname");
You Should Read This
If you use the direct prototype access method (Object.defineProperty is fine) and other code does not check hasOwnProperty, kittens die! Ok, to be honest, no harm comes to any kitten really but probably things will break and every other developer in your team will hate you:

See that last "SortBy"? Yeah. Not cool. Use Object.defineProperty where you can, and leave the Array.prototype alone otherwise.