var a = Array.prototype.slice.call(arguments,0)
Why does it return an array with all the arguments? I thought slice takes away arguments. What are the arguments and 0 parameters for?
Thanks,
Andrej
var a = Array.prototype.slice.call(arguments,0)
Why does it return an array with all the arguments? I thought slice takes away arguments. What are the arguments and 0 parameters for?
Thanks,
Andrej
slice
creates a slice of an array: it doesn’t take away anything - myArray.slice(0,5)
says "create a new array made up of the values from index 0 to index 5 in the array myArray
"
If you leave off the second argument, it slices up until the end of the array. So myArray.slice(0)
says "create a new array made up of all the values in myArray
(ie index 0 until the end)
call
is a function that allows you to literally call a function. The reason this is sometimes useful is that you can borrow functions from other objects.
slice
works on arrays, it is attached to the Array.prototype
object.
arguments
is an object that is available inside functions. It contains the arguments passed to the function. It is a bit like an array, but not quite.
If you want the arguments as an actual array, you can use slice(0)
on them. But you can’t use it directly, you need to borrow it by using call
. “Call the function slice
(borrowed from Array.protoype
) on the arguments
object to create a copy of the arguments in an actual array”
This is quite confusing, and not recommended any more, so avoid doing it: either use rest parameters if you can:
function example (...someArgs) {
// someArgs is already an array!
}
Or use Array.from
if you can’t:
function example() {
const args = Array.from(arguments);
}
Ok wow thanks for the awesome explanation! So are arguments and parameters different because parameters are defined when calling the function and arguments are not right??
function destroyer(arr) {
var args = Array.prototype.slice.call(arguments);
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < args.length; j++) {
if (arr[i] === args[j]) {
delete arr[i];
}
}
}
return arr.filter(Boolean);
}
This was the code, so the arguments were not defined but arr was for some reason. I dont know exactly why. Why doesnt arr count as an argument, is it a parameter?
How is args already an array I thought we were trying to convert it into an array with slice.call
Thanks
I thought it would be this challenge.
Just before the following, parameter
is the variable, argument
is the actual data, so for example
function add(x, y) { return x + y; }
add(1, 2);
The parameters are x
and y
, the arguments are 1
and 2
.
Example, I have a function that takes any number of numbers as arguments and adds them up:
function addNumbers(...nums) {
// nums is an array, don't need to
// convert anything
return nums.reduce((acc, num) => acc + num, 0);
}
So if I do addNumbers(1, 2, 3)
, in the function it will run reduce
on an array [1,2,3]
(returning 6)
function destroyer (arr, ...targets) {
With that function signature, arr
is the first parameter, and targets
will be represented inside the function as an array of the remaining arguments (the onces you want to destroy in arr
)
If I use rest parameters this way, I don’t need to do anything special to get the arguments: I’ve already explicitly defined them
It does count. In JavaScript, you can pass as many arguments as you want to a function: in this case, like
destroyer([1,2,3,4], 1, 2)
arr
is the first parameter – in this case the argument is [1,2,3,4]
. The other arguments in your code aren’t defined, and this is why you’re using slice. You need a way to get those remaining arguments. If you use rest parameters, it can be made explicit (this is why it is recommended in the documentation)
But if you don’t use rest parameters, then what you have to do is extract that 1
and 2
somehow. So can use Array.prototype.slice.call(arguments, 0)
, or can use Array.from(arguments)
(which is a lot clearer IMO)
function destroyer (arr) {
const args = Array.from(arguments)
args
is an array containing all the arguments, so for destroyer([1,2,3,4], 1, 2)
it’ll look like [[1,2,3,4], 1, 2]
Ok I am reading through and first wanted to ask
I thought …nums would spread the array not making it an array anymore. I thought the spread operator was used to get items out of an array
I dont know how to tag you but I posted a question
No, you’re misunderstanding. You’re not looking at how this function is called. This:
function addNumbers (...nums) {
Is
addNumbers
nums
)nums
addNumbers(1,2,3,4,5);
No array, the input isn’t an array.
In ES5, if you want a function (or method) to accept an arbitrary number of arguments, you must use the special variable
arguments
In ES6, you can declare a rest parameter via the...
operator
https://exploringjs.com/es6/ch_parameter-handling.html#sec_rest-parameters
In my other example
destroyer (arr, ...targets) {
arr
and targets
arr
is the first parameter, it represents a single argumenttargets
is the second parameter, it represents any number of remaining arguments.destroyer ([1,2,3,4], 1, 2)
The first argument is [1,2,3,4]
, that is assigned to the variable arr
. The second and third arguments are 1 and 2, they get assigned to the variable targets
as an array like [1,2]
It’s the rest operator, not spread: it’s very much connected, hence same syntax, but not quite the same.
Thanks so much! Howcome Array.from does not have Arra.prototype?
It’s just a function attached directly to the Array
object. Same as all Math
methods are just functions attached to an object called Math
, or see Object.keys
or Object.values
(or parseInt
or console.log
) or whatever.
It doesn’t need to be attached to a prototype, it doesn’t use this
. It needs to go somewhere rather than just floating around, so makes sense to attach it to the Array
object
// Array.prototype.slice
[1,2,3].slice(1)
^
|
`this`
Vs
Array.from({ 0: 1, 1: 2, 2: 3, length: 3})
// returns [1,2,3]