How to use the methods from other objects in JavaScript
Tags: javascript
Published: 2019-09-16 18:48:29

---
title: How to use the methods from other objects in JavaScript
published: true
description: call and apply allows you tu call the method's implementation through different objects
tags: javascript
---

I recently ran into this lines of code in JavaScript:

```javascript
[].slice.apply(arguments)
[].slice.call(document.querySelectorAll('foo'))
```

And although hard to read, this lines of code are so useful because they allow you to apple array specific methods to collections that not necessarily are arrays, such as NodeLists and the Arguments object.

But what are these lines of code doing and what can they tell us about the flexibility of JavaScript?.


# The how

According with the W3Schools, the slice method allows you to select and copy elements from one array into a new array. So the first thing that came to my mind while reading this line of code `[].slice.apply(arguments)` is, why are we calling slice in an empty array? If the purpose of this method is to select and copy elements from one array, how is it useful if we're calling it with an array that has no elements in it.

The thing is that this poor empty array is only exposing its precious slice method to be taken away. JavaScript allows you to change the context in which a method is called by using the apply and call methods. In other words, you can set the `this` value in a method' body, through call and apply.

Remember that every JavaScript function is actually an Object, and a clear example of it is that every JavaScript function has a call and an apply method, among another handful of methods that you can call through the function definition.

In practical words, for every JavaScript function, you can call other methods such as apply and call, for example:

```javascript
function foo(){}
foo.apply();
foo.call();
```

So what this line of code is doing `[].slice.apply(arguments)` is that changes the context from the empty array, to the arguments object, to make it seem that the object that called `slice` was `arguments` and not the empty array itself.

What makes this work is that the arguments object has some properties that are similar to the ones that arrays have, such as length, and these similarities allows the slice method to work with both arguments and arrays as context.

After the first argument, the apply method allows you to send the arguments that will be passed as the arguments to the function call, in this case when calling the slice method, since in this case we're only passing one argument, the arguments object, the slice method receives no arguments, which according with the documentation means that all the array elements will be copied into the new array, which in resume means that this line of code copies all the elements from the arguments object into a new array.

Now, talking about readability, this methods does exactly the same that the `Array.from` ES6 method does.

```javascript
Array.from(arguments) === [].slice.apply(arguments)
```

# The why

This particular line of code `[].slice.apply(arguments)` allows us to easily convert an object that looks and possible behaves like an array but that is not array, another common example aside from the arguments object is the NodeList objects such as the ones returned from the `querySelectorAll` function.

This is super useful because it allows us to play with the collection as an array, we can then plug the result into a loop, using it in combination with other array methods such as concat, includes, etc.


# Conclusion

What this line of code let me thinking about after reading it, was in how JavaScript allows us to call methods from objects that do not posses these methods in its prototype, which I believe fits into the duck typing philosophy that languages such as Ruby have made so popular.

So, as long as an object can provide the properties and methods for a method to work, you can set this object as the context of the method to effectively call a method from an object that does not have that object.

So, what do you think of the way JavaScript works in these scenarios? Let me know in the comments.

I'd also appreciate if you can report grammar errors or typos to me since english ain't my native language. Thanks in advance!