It was really confusing for me to read this syntax in Javascript:
router.route('/:id')
.put((...args) => controller.update(...args))
.get((...args) => controller.findById(...args));
What does ...args mean?
With respect to (...args) =>, ...args is a rest parameter. It always has to be the last entry in the parameter list and it will be assigned an array that contains all arguments that haven't been assigned to previous parameters.
It's basically the replacement for the arguments object. Instead of writing
function max() {
var values = Array.prototype.slice.call(arguments, 0);
// ...
}
max(1,2,3);
you can write
function max(...value) {
// ...
}
max(1,2,3);
Also, since arrow functions don't have an arguments object, this is the only way to create variadic (arrow) functions.
As controller.update(...args), see What is the meaning of "foo(...arg)" (three dots in a function call)? .
Essentially, what's being done is this:
.put((a, b, c) => controller.update(a, b, c))
Of course, what if we want 4 parameters, or 5, or 6? We don't want to write a new version of the function for all possible quantities of parameters.
The spread operator (...) allows us to accept a variable number of arguments and store them in an array. We then use the spread operator again to pass them to the update function:
.put((...args) => controller.update(...args))
This is transparent to the update function, who receives them as normal arguments.
The meaning of “…args” (three dots) is Javascript spread operator.
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers));
// expected output: 6
If you know some Python syntaxes, it is exactly the same as *args. Since *args (Python) is tuple object and Javascript has no tuple like Python, ..args is an Array object.
means pass all values (useful if have unknown# of items)
sample code
console.log(sum(1, 2, 3, 4)); // expected output: 10
function sum(...allItems) {
let total = 0;
for (const item of allItems) {
total += item;
}
return total;
}
It's called 'rest parameter', you can use rest parameter to pass unspecified number of arguments as an array, And a function can have only one rest parameter and it have to be the last parameter for the function
function sum(...args){
let output = 0;
for(const num of args){
output += num;
}
return output;
}
console.log(sum(2,4,8));
here it takes the argument that passed on sum as an array and sum the output and return it
Related
My point is this:
function sum(...arguments) {
if (arguments.length === 1) {
const [firstArg] = arguments;
if (firstArg instanceof Array) {
return sum(...firstArg)
}
}
return arguments.reduce((a, b) => a + b);
}
What is this ... are doing infront of arguments. And also please help me know that why const [firstArg] is given and how this is working. And please explain me instanceof in easy words. My native language is not english. Thank you so much.
That's the rest syntax:
The rest parameter syntax allows a function to accept an indefinite number of arguments as an array.
This:
const [firstArg] = arguments;
is destructuring assignment:
[it] makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
Re instanceOf:
The instanceof operator tests to see if the prototype property of a constructor appears anywhere in the prototype chain of an object. The return value is a boolean value.
Unpacking this code:
function sum(...arguments) {
// arguments is an array thanks
// to the rest syntax. If it has a length of
// one...
if (arguments.length === 1) {
// Get the first element
const [firstArg] = arguments;
// If that element is an array
if (firstArg instanceof Array) {
// Call sum again with that element
return sum(...firstArg)
}
}
// Return the sum of the arguments
return arguments.reduce((a, b) => a + b);
}
Your function could be easily simplified by flattening the arguments, and then using reduce to return the sum. And this way you can even have a set of single values passed in, or n multiple arrays as a single argument to the function, or a mixture of both.
function sum(...args) {
return args.flat().reduce((acc, c) => acc + c, 0);
}
console.log(sum(1, 2, 3));
console.log(sum([1], 1, 2, 3));
console.log(sum([1, 2, 3]));
console.log(sum([1, 2], [1, 4, 3]));
console.log(sum([1, 2], [12, 20], [1, 4, 3]));
(...arguments) is the rest parameter syntax and allows a function to accept an indefinite number of arguments as an array, providing a way to represent variadic functions in JavaScript.
for more information, you can read here
const [firstArg] = arguments;
is something named Destructuring assignment
The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
you can read more, here
and in the last, The instanceof operator tests to see if the prototype property of a constructor appears anywhere in the prototype chain of an object. The return value is a boolean value
This because ... is a javascript tool that allows you to put multiple parameters in a function it is called the rest parameter function.
Given an object and a key, getElementsThatEqual10AtProperty returns an array containing all the elements of the array located at the given key that are equal to ten.
I want to assign what my .reduce method outputs to a variable then use that variable inside my if statement. My code evaluates to NaN.
function getElementsThatEqual10AtProperty(obj, key) {
var arrayTotal = 0;
obj[key].reduce(function(a,b){
arrayTotal = a + b;
});
if(arrayTotal === 10) {
return obj[key];
}
};
You're approaching reduce incorrectly. You're almost using it like Array#forEach. Remember that callbacks are functions. They expect to return an actual value.
When you read the docs, you'll see that reduce also needs an accumulator, that is an argument after the callback.
const sum = obj[key].reduce(function(a,b){
return a + b
}, 0)
Or if you want the newer and prettier version:
const sum = obj[key].reduce((a,b) => a + b, 0)
When you have a one liner, return is implicit, which means it's implied, as opposed to explicit.
The accumulator is what your value starts at while it totals up the values.
Array.reduce(callback, accumulator)
I came across a weird code which I didn't understood. It would be great if I get explanation.
function forEach(array, action) {
for (var i = 0; i < array.length; i++) {
action(array[i]);
}
}
var numbers = [1, 2, 3, 4, 5], sum = 0;
forEach(numbers, function (number) {
sum += number;
});
console.log(sum);
How the function got passed as parameter ? and how the inner function is getting that number.
In JavaScript, functions are what's called first class citizens (that's not necessarily true for other languages), that means that functions can be treated as data, you can pass functions as arguments, return functions from other functions, and create functions and assign them to variables.
Here's a very simple example:
function callWithoutParams(fn) {
return fn(); // fn is the passed function.
}
let rand = callWithoutParams(Math.random); // Passing Math.random as a function.
callWithoutParams(() => console.log(42)); // Passing anonymous function
Array.prototype.forEach() accepts a function as an argument, and runs it on each element in the array. So a simpler example is:
[1,2,3,4,5].forEach((element) => console.log(element)); // outputs 1-5 in order.
In javascript, everything is an object, including function.
For simplicity, check this example:
var func = function(number){
console.log(number);
}
var arr = [1,2,3,4,5];
function foreach(data, callback){
for(var i = 0; i<data.length; i++){
callback(data[i]);
}
}
foreach(arr, func);
In JS, you can assign function to a variable. This is called as Function Expression. So it acts as a normal variable, just that its type is object.
This allows us to pass function as a parameter.
Now your second question, how the inner function is getting that number.
in your code, action(array[i]); is passing value as a parameter, so
function (number) {
sum += number;
}
here number is array[i].
I have an array of arrays:
var data = [[2,2], [6,4], [300,500]];
I have a function that takes some arguments and returns a single value.
var sum = function (a, b) { return a + b; }
I want to apply the function to each item in the array, e.g.
FOO(data, sum) === [sum(2,2), sum(6,4), sum(300,500)] === [4, 10, 800]
I was hoping underscore would have a function that does what "FOO" does. But I don't see anything. _.map is close, but not quite.
I know how to implement the function FOO.
var FOO = function (arrayOfArrays, iterator, context) {
return _.map(arrayOfArrays, function (array) {
return iterator.apply(context, array);
}
)};
My question is what to call FOO. I'm guessing the above pattern is common enough in functional programming that there's already a well established, language-agnostic name for this function.
It seems to me there is already a standard Javascript method for arrays, forEach(), that does what you want. For example:
data.forEach(sum);
So, do you really need a new FOO? If so, you could name it "forEach" and just wrap the above logic.
Here is the test code:
function fn(i, j) {
arguments = [3, 4];
console.log(i, j); // 1, 2
console.log(arguments); // [3, 4]
}
fn(1, 2);
in the function , I reset the arguments object
However, the arguments object is changed, but the formal parameter which passed in is not chaned, I think they are the same, so what's the differences?
arguments is an array-like object, which has reference to all the parameters passed to it. Here, you have merely reassigned arguments to point to some other object. If you want to change the actual parameters, you have to change the elements of arguments, like this
function fn(i, j) {
arguments[0] = -1;
console.log(i, j); // -1, 2
console.log(arguments); // { '0': -1, '1': 2 }
}
fn(1, 2)
Quoting from arguments, MDN docs
The arguments object is not an Array. It is similar to an Array, but
does not have any Array properties except length. For example, it does
not have the pop method.
However it can be converted to a real Array:
var args = Array.prototype.slice.call(arguments);
If Array generics
are available, one can use the following instead:
var args = Array.slice(arguments);
You are replacing the arguments array (actually an array-like object) with a new array. They are separate objects and exist side by side. Replacing the reference of the arguments variable doesn't make the function use the new array as arguments, it still has an internal reference to the original object.
If you change the contents of the arguments object, it will reflect on the function arguments:
function fn(i, j) {
arguments[0] = 3;
arguments[1] = 4;
console.log(i, j); // 3, 4
console.log(arguments); // [3, 4]
}
fn(1, 2);