I was going through the code of one of the chart library written in javascript, wherein I've seen passing underscore(_) as a function parameter. What does that mean?
chart.x = function(_) {
if (!arguments.length) return lines.x;
lines.x(_);
lines2.x(_);
return chart;
};
Can someone please update on this...Thanks.
The underscore symbol _ is a valid identifier in JavaScript, and in your example, it is being used as a function parameter.
A single underscore is a convention used by some javascript programmers to indicate to other programmers that they should "ignore this binding/parameter". Since JavaScript doesn't do parameter-count checking the parameter could have been omitted entirely.
This symbol is often used (by convention again) in conjunction with fat-arrow functions to make them even terser and readable, like this:
const fun = _ => console.log('Hello, World!')
fun()
In this case, the function needs no params to run, so the developer has used the underscore as a convention to indicate this. The same thing could be written like this:
const fun = () => console.log('Hello, World!')
fun()
The difference is that the second version is a function with no parameters, but the first version has a parameter called _ that is ignored. These are different though and the second version is safer, if slightly more verbose (1 extra character).
Also, consider a case like
arr.forEach(function (_, i) {..})
Where _ indicates the first parameter is not to be used.
The use of underscores like this can get very confusing when using the popular lodash or underscore libraries.
_ in fat arrow function is called as throwaway variable. It means that actually we're creating an variable but simply ignoring it.
More devs are now a days using this as syntactic sugar or short hand while writing code, as it's easy and one character less to write the code.
Instead of using _, you can use other variables like temp, x, etc
for examples:
() => console.log('Hello World')
_ => console.log('Hello World')
x => console.log('Hello World')
But personally i prefer to use () type over throwaway variable if no arguments are needed.
See the following code, then you will understand it better.
_ as an argument,
f = _=> {
return _ + 2 ;
}
f(3) will return 5
For better understanding, check wes bos
Related
I saw the following line in a node js code base.
_ => { return resolve(abc);}
Can any one give me some hint on what this _ means?
I know => is fat arrow function. This line is from a snippet of promise.
At the coaxing of a discussion elsewhere in this question, I'll turn my comments into an answer.
First off, I assume you aren't asking about arrow functions in general, but are just curious about the _ in your code sample.
There is a convention (used by some) to declare and name a parameter to a callback function that you know is passed, but you are not going to be using with an underscore as a sort of placeholder. It's a signal to people reading the code that there is an argument being passed to this callback, but you don't plan on using it in this particular invocation. It's presence is not functional, but more for
Now, without knowing what was in the head of the developer who wrote the line of code you asked about, we can't know for sure what the underscore means, but it does appear to match that previously described convention. There is one argument to the callback and it is not used in the implementation of the callback.
So, if our guess that this is a use of that convention is true, then in the arrow function that you show:
_ => { return resolve(abc);}
It is likely expecting one argument, but this particular use of that callback does not plan on using it, thus they named it with an _ just to signal that.
Now, there is no particular reason in Javascript that the callback needs to even define a single argument like this that be used. The callback could just as well have been defined as:
() => { return resolve(abc);}
since there's no requirement in Javascript that you declare arguments you aren't going to use.
If the callback took two arguments and it was the first one that you weren't going to use, then it does have to be declared as something in order to allow access to the second argument:
(_, secondArg) => { return resolve(secondArg);}
It means that the arrow function argument is not used. They use _ as argument name for the arrow function.
Doesn't this mean something like this?
function(_){
return resolve(abc);
}
What's happening here is that the code is using (some of) the concise syntax for arrow functions. To do this you'd write a function like this:
var f = x => x*x;
according to the docs
So with your example, the argument x is named with an _ (a valid character for variable names):
var f = _ => {return resolve(abc)}
But, it doesn't need the return or the brackets, either. It could be just:
_ => resolve(abc);
Perhaps a more readable way to write it would be with the parathesis:
() => resolve(abc);
I came across this construct in an Angular example and I wonder why this is chosen:
_ => console.log('Not using any parameters');
I understand that the variable _ means don't care/not used but since it is the only variable is there any reason to prefer the use of _ over:
() => console.log('Not using any parameters');
Surely this can't be about one character less to type. The () syntax conveys the intent better in my opinion and is also more type specific because otherwise I think the first example should have looked like this:
(_: any) => console.log('Not using any parameters');
In case it matters, this was the context where it was used:
submit(query: string): void {
this.router.navigate(['search'], { queryParams: { query: query } })
.then(_ => this.search());
}
The reason why this style can be used (and possibly why it was used here) is that _ is one character shorter than ().
Optional parentheses fall into the same style issue as optional curly brackets. This is a matter of taste and code style for the most part, but verbosity is favoured here because of consistency.
While arrow functions allow a single parameter without parentheses, it is inconsistent with zero, single destructured, single rest and multiple parameters:
let zeroParamFn = () => { ... };
let oneParamFn = param1 => { ... };
let oneParamDestructuredArrFn = ([param1]) => { ... };
let oneParamDestructuredObjFn = ({ param1 }) => { ... };
let twoParamsFn = (param1, param2) => { ... };
let restParamsFn = (...params) => { ... };
Although is declared but never used error was fixed in TypeScript 2.0 for underscored parameters, _ can also trigger unused variable/parameter warning from a linter or IDE. This is a considerable argument against doing this.
_ can be conventionally used for ignored parameters (as the other answer already explained). While this may be considered acceptable, this habit may result in a conflict with _ Underscore/Lodash namespace, also looks confusing when there are multiple ignored parameters. For this reason it is beneficial to have properly named underscored parameters (supported in TS 2.0), also saves time on figuring out function signature and why the parameters are marked as ignored (this defies the purpose of _ parameter as a shortcut):
let fn = (param1, _unusedParam2, param3) => { ... };
For the reasons listed above, I would personally consider _ => { ... } code style a bad tone that should be avoided.
The () syntax conveys the intent better imho and is also more type specific
Not exactly. () says that the function does not expect any arguments, it doesn't declare any parameters. The function's .length is 0.
If you use _, it explicitly states that the function will be passed one argument, but that you don't care about it. The function's .length will be 1, which might matter in some frameworks.
So from a type perspective, it might be more accurate thing to do (especially when you don't type it with any but, say, _: Event). And as you said, it's one character less to type which is also easier to reach on some keyboards.
I guess _ => is just used over () => because _ is common in other languages where it is not allowed to just omit parameters like in JS.
_ is popular in Go and it's also used in Dart to indicate a parameter is ignored and probably others I don't know about.
It is possisble to distinguish between the two usages, and some frameworks use this to represent different types of callbacks. For example I think nodes express framework uses this to distinguish between types of middleware, for example error handlers use three arguments, while routing uses two.
Such differentiation can look like the example below:
const f1 = () => { } // A function taking no arguments
const f2 = _ => { } // A function with one argument that doesn't use it
function h(ff) {
if (ff.length === 0) {
console.log("No argument function - calling directly");
ff();
} else if (ff.length === 1) {
console.log("Single argument function - calling with 1");
ff(1);
}
}
h(f1);
h(f2);
This is based off Bergi's answer, but I thought adding an example was a little more editing than I was happy to do to someone elses post.
In python _ is used as a throwaway variable. Is there an idiomatic accepted name in javascript?
Rigth now, you can use array destructuring, no need for a var.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
For example:
[,b] = [1,2];
console.log(b);
will output :
2
And the value 1 won't be assigned to any unused var.
There isn't an accepted throwaway variable naming in JavaScript like in Python. Although, generally in the software engineering world, engineers tend to call those variables:
dummy, temp, trash, black_hole, garbage.
Use these variable namings or whatever name that will imply to the engineer reading your code that these variables have no specific use.
With that in mind, I would strongly not recommend using signs such as below as a throwaway variable:
_, $
Unless there is an explicit convention like in Python, don't use these signs as a throwaway variable, otherwise, it may interfere with other naming conventions and libraries in other languages, like the underscore and the jQuery libraries in JS.
And of course, if you find a specific use for that variable later on, make sure to rename it.
Generally, you will declare the signature of a function as an array. Simply omit one of them
const foo = (bar,baz,) => bar+baz;
foo(3,4,5) // → 7
This obviously works as long as the declaration of function argument is the last one; unlike this answer, which is valid for already-declared variables embedded in arrays. This:
const foo = (, bar,baz) => bar+baz;
will fail with:
Uncaught SyntaxError: expected expression, got ','
You can hack your way into this using any expression. However, you'll need to use the self same expression in every invocation
const quux = ([], bar,baz) => bar+baz;
quux(42,3,4); // → Uncaught TypeError: (destructured parameter) is not iterable
quux([],3,4); // → 7
That constant can be anything, so you can as well call it "dummy", but you will still have to repeat in every invocation.
I came across this construct in an Angular example and I wonder why this is chosen:
_ => console.log('Not using any parameters');
I understand that the variable _ means don't care/not used but since it is the only variable is there any reason to prefer the use of _ over:
() => console.log('Not using any parameters');
Surely this can't be about one character less to type. The () syntax conveys the intent better in my opinion and is also more type specific because otherwise I think the first example should have looked like this:
(_: any) => console.log('Not using any parameters');
In case it matters, this was the context where it was used:
submit(query: string): void {
this.router.navigate(['search'], { queryParams: { query: query } })
.then(_ => this.search());
}
The reason why this style can be used (and possibly why it was used here) is that _ is one character shorter than ().
Optional parentheses fall into the same style issue as optional curly brackets. This is a matter of taste and code style for the most part, but verbosity is favoured here because of consistency.
While arrow functions allow a single parameter without parentheses, it is inconsistent with zero, single destructured, single rest and multiple parameters:
let zeroParamFn = () => { ... };
let oneParamFn = param1 => { ... };
let oneParamDestructuredArrFn = ([param1]) => { ... };
let oneParamDestructuredObjFn = ({ param1 }) => { ... };
let twoParamsFn = (param1, param2) => { ... };
let restParamsFn = (...params) => { ... };
Although is declared but never used error was fixed in TypeScript 2.0 for underscored parameters, _ can also trigger unused variable/parameter warning from a linter or IDE. This is a considerable argument against doing this.
_ can be conventionally used for ignored parameters (as the other answer already explained). While this may be considered acceptable, this habit may result in a conflict with _ Underscore/Lodash namespace, also looks confusing when there are multiple ignored parameters. For this reason it is beneficial to have properly named underscored parameters (supported in TS 2.0), also saves time on figuring out function signature and why the parameters are marked as ignored (this defies the purpose of _ parameter as a shortcut):
let fn = (param1, _unusedParam2, param3) => { ... };
For the reasons listed above, I would personally consider _ => { ... } code style a bad tone that should be avoided.
The () syntax conveys the intent better imho and is also more type specific
Not exactly. () says that the function does not expect any arguments, it doesn't declare any parameters. The function's .length is 0.
If you use _, it explicitly states that the function will be passed one argument, but that you don't care about it. The function's .length will be 1, which might matter in some frameworks.
So from a type perspective, it might be more accurate thing to do (especially when you don't type it with any but, say, _: Event). And as you said, it's one character less to type which is also easier to reach on some keyboards.
I guess _ => is just used over () => because _ is common in other languages where it is not allowed to just omit parameters like in JS.
_ is popular in Go and it's also used in Dart to indicate a parameter is ignored and probably others I don't know about.
It is possisble to distinguish between the two usages, and some frameworks use this to represent different types of callbacks. For example I think nodes express framework uses this to distinguish between types of middleware, for example error handlers use three arguments, while routing uses two.
Such differentiation can look like the example below:
const f1 = () => { } // A function taking no arguments
const f2 = _ => { } // A function with one argument that doesn't use it
function h(ff) {
if (ff.length === 0) {
console.log("No argument function - calling directly");
ff();
} else if (ff.length === 1) {
console.log("Single argument function - calling with 1");
ff(1);
}
}
h(f1);
h(f2);
This is based off Bergi's answer, but I thought adding an example was a little more editing than I was happy to do to someone elses post.
I've been re-reading Spencer Tipping's excellent Javascript in Ten Minutes and for the life of me can't figure out what is going on in this example of using lazy scoping to create syntactic macros:
var f = function () {return $0 + $1};
var g = eval (f.toString ().replace (/\$(\d+)/g,
function (_, digits) {return 'arguments[' + digits + ']'}));
g(5,6); // => 11 (except on IE)
In particular,
$0 and $1 are being replaced by a function definition -- how does that function get evaluated? (Presumably by eval(), but I'm not seeing this).
What is the purpose of the single underscore argument in the function -- if I take it out, the code no longer works. Presumably it's just a place holder, but why is it needed?
I'll agree with pst here, this code is pretty scary. It's horrific for
readability. It's neat, though:
f is defined as sort of a placeholder function. It seems to be the actual
macro itself; the numeric variables will be replaced when it's evaluated
into g. They act as positional, variadic arguments which we'll see below.
g is where the magic happens: the function definition of f is converted
to a string, and the numeric variables in the macro definition f are
replaced with references to the indexed arguments for as many numeric
variables there are in the definition of f (hence the regular expression
and call to replace). The underscore is just used because we don't care
about the first parameter to the callback for replace.
The whole thing is then evaled, once f is essentially expanded to the
following:
function () { return arguments[0] + arguments[1] }
So, it's neat, in that you could define f with as many positional numeric
arguments as you wanted:
var f = function() { return $0 + $1 + $2 }
and it'd get evaluated to
function() { return arguments[0] + arguments[1] + arguments[2] }
Neat, but useless, arguably dangerous, impractical and hard to read.
I probably wouldn't ever use it.
That code scares me. It should totally not be used. (Unless there is some really compelling justification to do so; I am not aware of any1 2.) Also, there is no "functional programming" demonstrated in the above code, excluding perhaps the use of a callback. But heck, even C can trivially do that as there was no closure involved.
_ is just a valid identifier (like foo or _foo or $0). Here is is used for "don't care" (the value is that of the entire matched text as the function is the "callback" for a RegExp match).
$0 and $1 are replaced by arguments[0] and arguments[1], respectively (remember this is a textual substitution of the functions "to string" value!). It could have been typed out manually without a "macro":
function () { return arguments[0] + arguments[1] }
Or what I would have done:
function (a,b) { return a + b }
The rest (Function.toString and eval(functionStr)) is nonsense to support the "macro" stuff which relies on: Function -> codeString -> alteredCodeString -> Function.
This code requires a working Function.toString that can emit "source as it was". I am not sure when IE started supporting this, but it appears to work in IE9.
1 This is a little white lie, but the only place I have used such an approach involved IE in a Sidebar Gadget where the DOM could be "prematurely unloaded" when a flyout was retracted and some other messiness with trying to invoke a function in another window context. An all-about messy situation..
2 The Functional JavaScript Library shows how much "macro magic" can be done without eval.