What is the best way to use parameters on JavaScript?
- use arguments variable
- define a parameter
function greet() {
console.log("Hello " + arguments[0]);
}
function greet(name) {
console.log("Hello " + name);
}
Well it depends on the usage. If you expect only to process one variable, then use the second one. If you don't know how many inputs you are processing, then you can use the first one.
// processing single input
function greetPerson(name) {
console.log("Hello " + name);
}
// processing multiple inputs that varies in number
function greetPeople(...people) {
if (people.length > 1) {
people.forEach(p => console.log("Hello " + p));
} else {
console.log("Hello " + people[0]);
}
}
Also, it's better to use the rest parameter so that your parameters that you passed in to the function would be an Array. The built in arguments object is not an array and does not let you Array methods such as forEach or map, which can be a pain if you need to use them.
Related
I am trying to call a function required number of times. To solve this, I am creating a function that takes rest parameters and iterating through the first argument. I am unable to unpack the rest arguments and pass it to the function. Is there a way that I could unpack and pass it to the function as parameters. Below is my working code. Is there a better way to make it work?
function hello(name) {
console.log("Hello "+ name);
}
function greet(name,time_of) {
console.log("Good " + time_of +" " +name);
}
function foo(times,x, ...args) {
for(i=0;i<times;i++) {
x(arguments)
//x(args); //works good for hello() but not for greet(). Doesn't pass them to second argument
x(args[0],args[1]); //This works but not scalable
//args.map((element) => x(element));
}
}
foo(2,hello,"Myname");
foo(3,greet,"Myname","Afternoon");
Just spread the args out again:
function hello(name) {
console.log("Hello " + name);
}
function greet(name, time_of) {
console.log("Good " + time_of + " " + name);
}
function foo(times, x, ...args) {
for (i = 0; i < times; i++) {
x(...args)
}
}
foo(2, hello, "Myname");
foo(3, greet, "Myname", "Afternoon");
function createMathOperation(operator) {
console.log(operator); //(augend, addend) => augend + addend
return (value, other) => {
return operator(value, other)
}
}
const add = createMathOperation((augend, addend) => augend + addend)
add(1,2)//3
I found the above function definition from lodash. I am trying to understand it but to no avail.
Right inside createMathOperation, I try to log operator and this is the value
(augend, addend) => augend + addend
I guess value and other is 1 and 2 but how?
And how return operator(value, other) works when operator is (augend, addend) => augend + addend
Can anyone convert it to longer human readable form for a better understanding instead?
This is the essence of functional programming you can pass in a function, return a function, and call the function you received as a parameter:
function createMathOperation(operator) {
console.log(operator); // This is a the function that performs the computation
// We return a new function (using arrow syntax) that receives 2 arguments and will call the original operator we passed in to createMathOperation
// The code inside this function is not executed here, the function is not invoked.
// The caller can take the returned function and executed 0-n times as they wish.
return (value, other) => {
// when we invoke add this is the code that gets called and the arguments we pass to add end up in value and other
console.log("Getting ready to compute " + value + " operator " + other);
return operator(value, other) // since operator is a function we just invoke it as we would any other function with the two arguments we got from whoever called us.
}
}
// add will contain the wrapped function that has our extra console.log
const add = createMathOperation((augend, addend) => augend + addend)
// The 'Getting ready ...' text has not been printed yet, nobody invoked the function that was returned yet, the next line will do so.
console.log(add(1,2))
// will output:
// Getting ready to compute 1 operator 2
// 3
A note on => is just syntactic sugar over a function expression, it has extra semantics around this, but for this example, (augend, addend) => augend + addend is equivalent to function (augend, addend){ return augend + addend; }
createMathOperation returns function, which adds two numbers. Here's more readable version:
function createMathOperation(fn) {
console.log(fn);
return function(value, other){
return fn(value, other);
};
}
const add = createMathOperation(function (augend, addend) {
return augend + addend;
});
add(1,2)//3
I renamed 'operator' to 'fn' to make it less confusing (syntax highlighting colored it blue for some reason).
Your code in good old JS would look like:
var createMathOperation = function(operator) {
// operator is scope-locked within this operation wrapper
console.log('operator:', operator);
return function(value, other) {
// The wrapper returns an anonymous function that acts as a call-wrapper
// for your original function
console.log('value:', value);
console.log('other:', other);
return operator(value, other)
}
}
var add = createMathOperation(function(augend, addend) {
// This is what is being called at line 9 - return operator(value, other)
return augend + addend;
});
console.log('result 1+2:', add(1,2));
In general i don't see much use to all of this, you could just do const add = (a, v) => a + v; and have the same result.
In Javascript, I have seen the callback function is passed as the last parameter I am curious why so? Is it a good practice or standard way?
For example:
var doSomething = function(fname, lname, callback){
console.log("Your name is :"+ fname +" "+ lname);
callback();
}
var callback = function(){
console.log("Your name is printed successfully."):
}
doSomething('Arpit', 'Meena', callback); // callback is last parameter here
I know we can pass it at any position and it works but I just want to know the reason behind this.
Thanks.
The reason I do this way and have seen others doing so is because of code readability, when you have a calback as the last argument, you can declare the callback inline without making the code unreadable. For example, if you pass the callback as the first parameter:
var doSomething = function(callback, fname, lname){
console.log("Your name is :"+ fname +" "+ lname);
callback();
}
You have to call it like:
doSomething(function callback(){
console.log('foo');
}, 'Arpit', 'Meena');
However, if you use it as the last argument, things are kept much more clear on the function call:
var doSomething = function(fname, lname, callback){
console.log("Your name is :"+ fname +" "+ lname);
callback();
}
doSomething('Arpit', 'Meena', function callback(){
console.log('foo');
});
It is standard JavaScript convention. Part of the reason it has become standard practice is that it makes things more readable. It's like defining properties at the top of a class - you don't have to but it's standard practice.
Suggested reading:
http://technosophos.com/2012/08/22/javascript-callbacks-function-last%E2%80%A6-or-lost.html
http://hancic.info/callback-parameter-should-always-be-last
I am trying to pass an additional variable (devicename) into session.pingHost so that only once the ping has returned a response do I run another function (someOtherFunction) which requires the variable. Currently someOtherFunction receives devicename as undefined.
How would I accomplish this? Is there a better way of doing it?
var ping = require("net-ping");
var pingresult = '';
pingDevice('xxx.xxx.xxx.xxx', 'My Device');
function pingDevice(ipaddress, devicename){
var options = {
retries: 1,
timeout: 2000
};
var session = ping.createSession (options);
session.pingHost (ipaddress, function (error, target) {
if (error) {
console.log (target + ": ping FAIL");
pingresult = '0';
} else {
console.log (target + ": ping OK");
pingresult = '1';
}
someOtherFunction(pingresult,devicename);
});
}
The way you're doing it, using the fact that the callback is a closure over the context of the call to pingDevice (which contains the devicename argument), is entirely standard, normal practice. You can do exactly what you're doing, and given the code shown, it's what I would do.
Another way to do it is to use Function#bind:
session.pingHost (ipaddress, function (devicename, error, target) {
// ------------------------------------^^^^^^^^^^
if (error) {
console.log (target + ": ping FAIL");
pingresult = '0';
} else {
console.log (target + ": ping OK");
pingresult = '1';
}
someOtherFunction(pingresult,devicename);
}.bind(null, devicename));
//^^^^^^^^^^^^^^^^^^^^^^
Function#bind creates a new function that, when called, will call the original with a specific this value (we're not using that here, hence the null) and any arguments you give bind, followed by the arguments the new function was called with.
But I don't see any need for that here. The only real reason you'd need or want bind would be if you wanted to grab the value of devicename as of when you created the function (because it might change).
There is an unrelated problem: You're falling prey to The Horror of Implicit Globals because you don't declare your pingresult variable. Always be sure to declare your variables, in the appropriate context.
Please help in understanding the below code:
// define our function with the callback argument
function some_function(arg1, arg2, callback) {
// this generates a random number between
// arg1 and arg2
var my_number = Math.ceil(Math.random() * (arg1 - arg2) + arg2);
// then we're done, so we'll call the callback and
// pass our result
callback(my_number);
}
// call the function
some_function(5, 15, function(num) {
// this anonymous function will run when the
// callback is called
console.log("callback called! " + num);
});
In the above code,what is the callback keyword.what is the use of this word.
Even there is no function defined with name callback.
The gap in logic I think you're having a hard time with is anonymous, unnamed functions. Once upon a time, all functions were named. So code was written like this:
function MemberProcessingFunction() {
// etc
}
function AdminProcessingFunction() {
// etc
}
var loginProcessingFunction;
if (usertype == 'BasicMember') {
loginProcessingFunction = MemberProcessingFunction;
}
else if (usertype == 'Admin') {
loginProcessingFunction = AdminProcessingFunction;
}
loginProcessingFunction();
Someone thought "This is dumb. I'm only creating those function names to use them in one place in my code. Let's merge that together."
var loginProcessingFunction;
if (usertype == 'BasicMember') {
loginProcessingFunction = function() {
// etc
};
}
else if (usertype == 'Admin') {
loginProcessingFunction = function() {
// etc
};
}
loginProcessingFunction();
This especially saves a lot of time when you're passing a function to another function as an argument. Often, this is used for "callbacks" - occasions where you want to run certain code, but only after a certain indeterminately-timed function has finished its work.
For your top function, callback is the name of the third argument; it expects this to be a function, and it is provided when the method is called. It's not a language keyword - if you did a "find/replace all" of the word "callback" with "batmanvsuperman", it would still work.
'callback' is a function passed as an argument to the 'some_function' method. It is then called with the 'my_number' argument.
when 'some_function' is actually being called as seen below
// call the function
some_function(5, 15, function(num) {
// this anonymous function will run when the
// callback is called
console.log("callback called! " + num);
});
it receives the whole definition of the third function argument. so basically your 'callback' argument has this value below
function(num) {
// this anonymous function will run when the
// callback is called
console.log("callback called! " + num);
}
To understand better how a function can be passed as an argument to another function, take a look at this answer.