0

I'm reading trough this: https://hackernoon.com/functional-javascript-resolving-promises-sequentially-7aac18c4431e

and in one section the author talks about replacing the second arrow function with

Promise.resolve([])
    .then(all => funcs[0].then(result => all.concat(result)))

this

Promise.resolve([])
    .then(all => funcs[0].then(Array.prototype.concat.bind(all)))

I'm having trouble understanding how this works... Is the returned result being added as an argument implicitly into the concat function?

2
  • 2
    When calling a function that expects a function as an argument, you can either write a new function inline, e.g. foo(() => {...}) or pass a reference to an existing function, e.g. foo(myCallback). This example is using the bind() function to do the latter. But personally I don't see the advantage of using bind() in this situation; generally arrow functions are clearer with no performance downside (at least nowadays). Commented Mar 11, 2018 at 23:34
  • Well technically the bind() call isn't a reference to an existing function but returns a new function, but it's the same general idea - using an existing function instead of creating a new one inline. Commented Mar 11, 2018 at 23:35

3 Answers 3

1

whatEverMethod.bind(thisValue) binds this to thisValue.

To understand, we can assume (though not actually) every method call

obj.method(arg0)

to equal to

obj.method.apply(obj, arg0)

where the first argument of .apply explicitly tells: which object I am working on (because likely in the definition of .method you may reference to some this value, such as this.prop0 = 10)

What bind does is very simple: bind a this value to a method call, so that when called, no longer uses the default this value based on environment.

For example:

let obj0 = {a: 1}
let obj1 = {a: 2}
obj0.change = function(value) {
  this.a = value;
} // when declared, default environment is obj0, since it is a method of obj0

// Now, explicitly bind `this` inside of obj0.change to obj1
let changeFunc = obj0.change.bind(obj1);
// This creates a function that has `this` set to obj1, which has the format changeFunc(value)
changeFunc(10);

console.log(obj1.a) // should be 10, since it is now operating on obj1 (due to binding)

Therefore,

(Array.prototype.concat.bind(all))(someArr)
// is basically
all.concat(someArr)
// due to having the exactly the same `this` value

The reason why we may want to do this is probably all may not be an array. For example, it might be an array-like object, such as the arguments for functions, which looks like an array, but missing common array methods.

Sign up to request clarification or add additional context in comments.

Comments

0

bind operates on a function, taking a value for this and returning a new function that calls the original function with the specified this value and the same arguments¹. In other words,

Array.prototype.concat.bind(all)

means

(...args) => Array.prototype.concat.call(all, ...args)

which is

(...args) => all.concat(...args)

and since one argument is being passed, that’s

result => all.concat(result)

There is no reason not to just write the arrow function here, by the way. It’s clearer and has no downsides.

¹ it can also add arguments.

Comments

0
  • As you must know, the function then receives a function/callback.
  • The function bind returns a function attaching a specific object as context this.

 Array.prototype.concat.bind(all))
                             ^
                             |
                             +---- This object 'all' will be the context
                                   'this' for the function 'concat'.

So, the function then will call the callback (passing the all object implicitly) which is the new function returned by the function bind, in this case, the function concat from Array prototype.

Resource

  • Function.prototype.bind()

    The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.