1

I understand how this works but cant understand why we want to use apply with "this" keyword as in a example below:

function curry(func) {
    return function curried(...args) {

        if (args.length >= func.length) {
            return func.apply(this, args)
        } else {
            return curried.bind(this, ...args)
        }
    }
}

Here bind and apply use "this" as a first argument, but what is the purpose if we can just do func(args) since this points to same lexical environment of a function. I can see some benefits with it with arrow functions but here I have named functions. There is no difference or I am missing something?

Yerni
  • 55
  • 4

1 Answers1

3

The reason for using apply is to keep the same the value of this. Calling func(args) would result in this being the window object (in non-strict mode) or undefined (in strict mode).

Here's an example that breaks if you call func(args):

function curry(func) {
  return function curried(...args) {
    if (args.length >= func.length) {
      return func(args);
    } else {
      return curried.bind(this, ...args);
    }
  };
}

const example = {
  multiplier: 5,
  calculate: function (a, b) {
    return (a + b) * this.multiplier;
  },
};
example.curriedVersion = curry(example.calculate);

// Because of the way these are being called, `this` should be `example`
console.log(example.calculate(1, 2));
// But here it's not, causing unexpected results
console.log(example.curriedVersion(1)(2));

But it works if you do apply(this, args):

function curry(func) {
  return function curried(...args) {
    if (args.length >= func.length) {
      return func.apply(this, args);
    } else {
      return curried.bind(this, ...args);
    }
  };
}

const example = {
  multiplier: 5,
  calculate: function (a, b) {
    return (a + b) * this.multiplier;
  },
};
example.curriedVersion = curry(example.calculate);

// Because of the way these are being called, `this` should be `example`
console.log(example.calculate(1, 2));
console.log(example.curriedVersion(1)(2));
Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98
  • I have question why calling func(args) would result in this being the window object, is not it by default equals to instance of function, i.e example? – Yerni Jan 23 '22 at 05:32
  • 1
    `why calling func(args) would result in this being the window object` That's the default value for `this`; if you don't tell javascript what `this` should be, then you get `window` (or `undefined` in strict mode). The most common way to specify `this` is to write code where you access the property of an object, as in `example.calculate()`. The `example.` part tells javascript "when you call the function, set `this` to `example`". Other ways to set `this` include `bind`, `apply`, and `call`. For more info, see https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work – Nicholas Tower Jan 23 '22 at 12:27