3

i have a problem understanding this code or with Method Borrowing ->

   function func() {
      [].join.call(arguments)   //how does this works?
   {

join only needs a separator, why we are passing the this context value? and more interesting is that it work!

is there anybody to explain this to me?

:)

MORA
  • 137
  • 1
  • 8
  • 1
    `arguments` is an array-like object, but it doesn't contain `join` method. You're borrowing `join` from an array, and call its `join` method in the context of `arguments`, which then results a string containing the values in the arguments, not the values of the empty array (if you'd pass the delimiter argument too). – Teemu Feb 03 '22 at 10:33

1 Answers1

1

The .call() method is used on functions, it behaves in a similar way to using () to call a function such as when you perform functionName(), however, it allows you to explicitly define what the this is inside of the function, so for example:

function functionName(arg) {
  console.log("this", this); // this {"foo": 1}
  console.log("arg", arg); // arg str
}

functionName.call({foo: 1}, "str");

Notice that above, the first argument to .call() defines what this is inside of your function, and then the second argument onwards defines what the arguments are to functionName.

We can use .call() on any function, including the ones provided to us by JavaScript. In your code, you're using [].join which exposes (not calls) the join function of arrays, that is, it gives you access to the join function defined on the Array.prototype object. With that in mind, your code could be rewritten like so to highlight that [].join is used just to obtain the join function from the array prototype:

function func() {
  const joinFn = Array.prototype.join; // or: [].join;
  console.log(joinFn.call(arguments));
}
func('a', 'b', 'c'); // "a,b,c"

Internally, the .join() method on arrays uses this inside of it (similar to how functionName() uses this inside of it) to determine what object/array needs its elements to be "joined" together. In your example, you are not calling .join directly on your empty array (ie: [].join()), but instead, are using the empty array to access the .join function, and then calling it with the arguments object by using join.call(arguments). When you do this, the this inside of the .join() method is set to the arguments object and the join method is called with no arguments, so the separator defaults to ,. As the arguments object is array-like (it has indexes and a length property like an array does), its elements can be joined together just like an array's elements can be joined together.

You can see section 23.1.3.15 of the ECMAScript specification for further details on how Array.prototype.join works internally and how it is made generic to handle array-like objects and not just arrays.

Nick Parsons
  • 45,728
  • 6
  • 46
  • 64