Javascript Function.prototype.bind() with inline object definition

103 views Asked by At

While I was working with the bind() function, I came across a situation I am currently not aware of. Can someone give me and explanation why this example works like this? Apparently the inline object passed to the bind function is initialised only in the first iteration and then a reference is kept. I was not able to find any documentation about this, if you can point me to the right direction I will be veeeery grateful :-)

class test {

 addLetter(element) {
  console.log('addLetter', this.str);
  this.str += element + ',';
 }

 foo() {
  let arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

  arr.forEach(this.addLetter.bind({
   str: ''
  }));
 }
}

let a = new test();
a.foo();

OUTPUT:
addLetter 
addLetter a,
addLetter a,b,
addLetter a,b,c,
addLetter a,b,c,d,
addLetter a,b,c,d,e,
addLetter a,b,c,d,e,f,
2

There are 2 answers

1
Barmar On BEST ANSWER

It's easier to see if you separate the argument from the function call. A function call like:

someFunc(<expression>);

is equivalent to:

var tempVar = <expression>;
someFunc(tempVar);

So in your case, it's like this:

var tempVar = this.addLetter.bind({
   str: ''
});
arr.forEach(tempVar);

This makes it clearthat we're only calling bind() once, when we set tempVar. It creates a function that's bound to a specific object. Then forEach calls that function repeatedly. We can further break it down to:

var tempObj = { str: '' };
var tempFun = this.addLetter.bind(tempObj);
arr.forEach(tempFun);

Now it should really be clear why there's just a single object that gets reused each time the function is called.

5
trk On

the first argument to .bind() is the context. In this case it is the

{
    str: ''
}

Now, you are referencing it and using its str property within. Now, we know .bind() returns a function. That function happens to be called within .forEach().

This bind generated function receives as its first argument an element (depending on the iteration).

For the first time iteration index is zero and the bind generated function function receives 'a' as its argument.

Statement

this.str += element + ',';

enhances str as '' + 'a'. In the second iteration, the argument is 'b' and that gets appended to 'a,' + 'b' and so on.

Hence you see the result you see. Let me know if this clarifies your question.