-1

I'm studying currying functions in JS and I got stuck with this problem.

My goal is to order an array of objects by a non-arbitrary property.

let people = [
    { name: 'Bob', age: 27 },
    { name: 'Al',  age: 47 }
];

var compare = function(a, b) {
    if (a[property] < b[property]) return -1;
    if (a[property] > b[property]) return 1;
    return 0;
};

function sortBy(property) {
    /* // this works
    return function compare(a, b) {
        if (a[property] < b[property]) return -1;
        if (a[property] > b[property]) return 1;
        return 0;
    };
    */

    // this doesn't work
    return compare;
}

people.sort(sortBy('name'));
console.log(people);

With this code I get this error:

if (a[property] < b[property]) return -1;
          ^
ReferenceError: property is not defined

Why if I define the compare function inside the sortBy function I don't get any error, and instead if I define the compare function outside I get an error?

The compare function should not be enclosed in a closure?

Couper
  • 414
  • 5
  • 13
  • 2
    JavaScript has lexical scoping, not dynamic one. [Wikipedia](https://en.m.wikipedia.org/wiki/Scope_(computer_science)) – Jonas Wilms Aug 03 '20 at 13:52
  • "The compare function should not be enclosed in a closure?" Why? – Jonas Wilms Aug 03 '20 at 13:53
  • 1
    Because there’s no “property” when... there’s no “property”. I’m not sure what you’re expecting or asking—if you want “property” available it has to exist. – Dave Newton Aug 03 '20 at 13:54
  • 2
    In this line ` if (a[property] < b[property]) return -1;` , what would `property` even refer to? You're not passing it into the function, nor is it a global variable, or locally accessible. However it IS locally accessible when you define the function inside `sortBy` – TKoL Aug 03 '20 at 13:54

1 Answers1

0

The best I can find is using .bind, but it's not perfect as it forces you to add this in compare which means you can't use it without having it binded

This happens because returning a function doesn't bind the current scope to it unless it was created in the current scope this question may help understand better

let people = [
    { name: 'Bob', age: 27 },
    { name: 'Al',  age: 47 }
];

var compare = function(a, b) {
    if (a[this.property] < b[this.property]) return -1;
    if (a[this.property] > b[this.property]) return 1;
    return 0;
};

function sortBy(property) {
    return compare.bind({property});
}

people.sort(sortBy('name'));
console.log(people);
jonatjano
  • 3,576
  • 1
  • 15
  • 20