Reputation:
and then call them using call()
?
For example slice can be called directly as such
obj.slice(1);
but underscore does
slice.call(obj, 1);
What is the reason for this?
Upvotes: 2
Views: 89
Reputation: 1877
I don't have much experience with underscore, but I assume it is due to underscore using array like objects instead of arrays.
In that case, it does not have the methods of an array, and so you have to use the call method.
See examples below:
function List(){
this.length = arguments.length;
//arguments is an array like object, not an array, does not have a foreach method
Array.prototype.forEach.call(arguments, function(val, index){
this[index] = val;
}, this);
}
var list = new List(1,2,3,4,5);
console.log(list); //{ '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, length: 5 }
//Cannot use push on on object List
//list.push(6); //TypeError: undefined is not a function
//But you can use call()
Array.prototype.push.call(list, 6);
console.log(list);
//{ '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, length: 6 }
http://repl.it/UZX link to the examples above
Edit: I missed something important.
The implimentation of slice that you see is achieved by by setting var slice = Array.prototype.slice
slice.call()
is used so that the slice method has a this variable to refer to.
Check out the below example:
var push = Array.prototype.push;
push.call(list, 7);
console.log(list);
//{ '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, '6': 7, length: 7 }
List.prototype.push = push;
list.push(8);
console.log(list);
//{ '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, '6': 7, '7': 8, length: 8 }
Upvotes: 0
Reputation: 887413
In case obj.slice
isn't what you think it is.
In particular, array-like objects like arguments
or NodeLists do not have a slice
method.
Upvotes: 1