Standard conventions for indicating a function argument is unused in JavaScript - javascript

Are there any standard ways of marking a function argument as unused in JavaScript, analogous to starting a method argument with an underscore in Ruby?

Just so we have an example to work from, this is fairly common with jQuery's $.each where you're writing code that doesn't need the index, just the value, in the iteration callback and you're using this (which jQuery also sets to the value) for something else:
$.each(objectOrArrayLikeThing, (_, value) => {
// Use `value` here
});
(Yes, $.each passes arguments to the callback backward compared to the JavaScript standard forEach.)
Using _ is the closest I've seen to a standard way to do that, yes, but I've also seen lots of others — giving it a name reflective of its purpose anyway (index), calling it unused, etc.
If you need to ignore more than one parameter, you can't repeat the same identifier (it's disallowed in strict mode, which should be everyone's default and is the default in modules and class constructs), so you have do things like _0 and _1 or _ and __, etc.

Using destructuring assignment, one can do:
function f(...[, , third]) {
console.log(third);
}
f(1, 2, 3);

With browsers supporting destructuring one can do:
function ({}, {}, value) {
// console.log(value)
}
Which is kind of neat in that it avoids the problem of multiple arguments having the same name and also won't create problems with libraries that assign methods to _ (lodash, underscore, etc.).
One problem with this approach is that unused arguments of type undefined or null will throw.
For undefined one solution is to use default parameters:
function ({}={}, {}={}, value) {
// console.log(value)
}
Sadly no such easily applied solution for null.

I would recommend this syntax:
function(_index, value) {...}
to not to shadow lodash variable and still have description of argument in case if it will be used.
VS Code is also highlight these names properly and these unused args won't be deleted after autofix code smells

How about using the function arguments object?
function third() { const [,,thirdArg] = arguments;
return thirdArg;
}
console.log(third(1,2,3));

Another approach: For unused parameters to be ignore from unused errors using:
function(_1, _2, toBeUseParam) { ... }

Related

passing single argument into a function that requires multiple arguments in javascript

I'm trying to read through some source code on the internet, and I'm getting confused because the author defined a function as:
var _0x80a1 = function (x, a) {...}
But then only calls it using statements like this:
_0x80a1("0x0")
How does that work?
JavaScript parameters are optional you don't need to pass them. So you can do something like this:
function multiply(a, b) {
if(typeof b === 'undefined') {
b = 10;
}
return a * b;
}
console.log(multiply(5));
// expected output: 50
In newer versions of JS you can also do default parameters like this:
function multiply(a, b = 10) {
return a * b;
}
console.log(multiply(5));
// expected output: 50
No function "requires" an argument in JavaScript. It's not a strongly typed language.
I might be typing out of my own butt, but I think function's arguments are syntactic sugar in JS. You can always pass any amount of arguments, regardless of the function's "signature", because the only thing that identifies a function in JS, is its name (and the object on which it is called). That is why, the arguments object exists.
So, as others pointed it out, the second, third, or any other argument that wasn't given will simply be undefined.
An answer on this subject with examples
In ,JavaScript function parameters are optional.If your'e not making use of 'a' inside your function then JS compiler don't care about that.If your'e making use of 'a' inside your function then you will encounter some error like "a is undefined".
function (x,a=10){
}
You can set default parameters like this.Now even if your'r passing one parameter to your function it will run without any errors
I was curious so tried to understand this a bit so I could try to answer.
The variable _8x80a1 is a literal bit definition (https://www.hexadecimaldictionary.com/hexadecimal/0x80A1/) representing e.g. 32929 in decimal.
I'm guessing JS internally numbers all functions when its run. This leaves an entire integer (32766) 'vanilla' functions that can be compiled before using a literal as a function name might cause a conflict.
So the 'x' in the function def. looks like it's passing a string, but it might be just calling 'Function #0' in the _8x80a1 var/function. This would make sense if the function contains multiplpe 'sub functions', as then the 'a' variable can be an object collection (e.g. parameters), that can be passed to the sub-function.
Roughtly, I think .. Not used JS for a whilst and just thought I'd try to help answer! ;-) Essentially a compact way to make a toolkit you can copy between projects, and know your references will all work as expected to your tools, without disrupting e.g. jQuery or other scripts. (Wouldn't be surprised if this is how JS is minified actually ;)).
Chris

What does this underscore mean in node js

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);

Parameter names with ES6?

I have defined a function like:
function call_api(url, callback, query = {}, body = {})
I expected a syntax where I can provide body and skip query:
call_api('/api/clients/new', function(x){console.log(x)}, body={1:2})
But I have to use this workaround:
call_api('/api/clients/new', function(x){console.log(x)}, {}, {1:2})
Even if I provide body=, it appears its appearing as the query parameter. I use Babel with Webpack. I tried the syntax in Chrome console and in Webpack source.
Is such a syntax supported by ES6? How does it work?
I recommend that you work around this with passing an object and using destructuring for objects:
function callApi({url, callback, query = {}, body = {}})
And then call it as:
callAPI({url: "/api/..", callback: (x => console.log(x)), body: {a:2}})
Which would give you syntax similar to the one you want.
Named arguments have been considered and rejected for JavaScript, unlike other languages like C# and Python which sport them. Here is a recent discussion about it from the language mailing list.
As shown on this site, the defaults are just for parameters that need a default value (like an options parameter), but not for 'skipping' parameters.
What you're trying to do is
// function definition
function hi(a,b,c,d)
// function call
hi(a,b,d)
ES6 is still going to think that your 'd', is the defined c, regardless of your default value.
So no, ES6 does not have such syntax.
You can't specify which parameter you assign to in your call.
call_api('/api/clients/new', function(x){console.log(x)}, body={1:2})
Is equivalent to setting a variable named body outside of the function and then passing its value in the query parameter's spot.
You could use destructuring to achieve what you want though.
function call_api(url, callback, {query = {}, body = {}} = {})
Then in your call you would do this
call_api('/api/clients/new', function(x){console.log(x)}, {body:{1:2}})
Seeing that the default parameter value is only used when the parameter is undefined, the only way to "skip" a parameter and fall back to the default would be to send undefined in it's place:
call_api('/api/clients/new', function(x){console.log(x)}, undefined, {1:2})
Example: Babel REPL
The value of query within the function will be {} (or whatever you set default to) in this case.
This would be somewhat similar to what Visual Basic does when you want to use the default parameter value by passing an empty value. (e.g. sub name(argument 1, , , argument 4))
Otherwise, if you wanted support for named parameters, the best compromise would be the answer supplied by #Benjamin Gruenbaum.
Update: You might find this article provides an option using the arguments keyword, or better yet, you could iterate over the ES6 ...rest parameters collection to simulate an overloaded function in Javascript.

Why does my JavaScript function accept three arrays, but not an array containing three arrays?

function product() {
return Array.prototype.reduce.call(arguments, function(as, bs) {
return [a.concat(b) for each (a in as) for each (b in bs)]
}, [[]]);
}
arr4=[['4','4A','4B'],['16D','15D'],['5d','5e']];
alert(product(['4','4A','4B'],['16D','15D'],['5d','5e']);
The above works but the following don't work:
arr4=[['4','4A','4B'],['16D','15D'],['5d','5e']];
alert(product(arr4);
Thanks for suggestions
You can have either one or the other; otherwise it's poorly defined. (Unless you want to make the very questionable decision to do special-casing like "if my first argument is an array and each element is an array, return something different". Then you'll be remaking PHP in no time. =])
Use the somefunction.apply method instead; that's what it was made for. For example:
product.apply(this, arr4)
Is equivalent to:
product(arr4[0], arr4[1], ...)
If you do this a lot, you can define product2(arrays) {return product.apply(this,arrays)}.
However unless you want to do both product([..], [..], ..) and product([[..],[..],..]), this seems inelegant.
If you want this function to behave by default like product([[..],[..],..]), then the correct way to solve this is to modify the function to suit your needs. It is currently using the default "variadic" (multiple arguments) arguments variable special to javascript, which stands for an array representing all the arguments you passed into the function. This is not what you want, if you want normal-style fixed-number-of-arguments functions. First add in the appropriate parameter:
function product(arrays) {
...
}
and rather than using the default arguments variable, replace that with arrays.

javascript function chaining without the chain members knowing about each other

I want to create a javascript pipeline like powershell, bash (|) or f# (|>). Ie. something equivalent to
getstuff() | sort() | grep("foo") | take(5)
I saw a discussion about this in coffeescript forum but in the end they shelved it because everybody said that you could do the same thing with function chaining. But as far as I can see that requires getstuff returns something that has a sort method on it; the sort method must return something that has grep method on it etc. This is pretty restrictive as it requires all potential pipeline members to know about each other in advance. I know JavaScript has some pretty clever tricks in it and I am still at the 101 level - so is this doable
getstuff().sort.().grep().take()
without that constraint
is this doable
getstuff().sort.().grep().take()
without that constraint
No.
I like short answers! Can you suggest any way that something like it could be done
At a high level, you could do something similar to what jQuery does under the hood to allow chaining. Create an array-like wrapper object type which has all of the functions you want to be able to call; each successive chained call can operate on an internal stack in addition to the explicitly-passed arguments.
Not to keep beating the dead jQuery horse, but one of the best ways to understand what I'm talking about is to just start digging through the jQuery core source code and figure out how the chaining works.
Defining an object to support the kind of function chaining you want is actually quite easy:
getStuff = ->
sort: ->
# set #stuff...
this
grep: (str) ->
# modify #stuff...
this
take: (num) ->
#stuff[num]
That's all you need to make getstuff().sort.().grep('foo').take(5) work.
You can make those calls without worrying about the return values having the appropriate methods like so:
take(5, grep("foo", sort(getstuff())));
But, that doesn't get through the problem of each function needing to be passed data that is meaningful to it. Even JavaScript isn't that slippery. You can call sort() on an image (for example,) but there's no meaningful way to generate results.
You could do something similar by returning a special object that has all required methods on it, but can be used instead of the final value. For example, you could return an Array instance that has all these methods on it.
var getstuff = function () {
obj = Array.apply(this, arguments);
obj.take = function (n) {
return this[n];
};
obj.grep = function (regexp) {
return getstuff.apply(this, Array.prototype.filter.apply(this, [function (item) {
return item.toString().search(regexp) !== -1;
}]));
};
obj.splice = function () {
return getstuff.apply(this, Array.prototype.splice.apply(this, arguments));
}
return obj;
}
// shows [-8, 1]
console.log(getstuff(3, 1, 2, 'b', -8).sort().grep(/\d+/).splice(0, 2));
// shows 3
var stuff = getstuff(3, 1, 2, 'b', -8).grep(/\d+/);
console.log(stuff.sort()[stuff.length]);
Note that the above is not a particularly fast implementation, but it returns arrays with special methods by still keeping the global Allay's prototype clean, so it won't interfere with other code.
You could make it faster by defining these special methods on the Array.prototype, but you should be careful with that...
Or, if your browser supports subclassing Array, then all you need is a supclass and a handy constructor, getstuff().

Categories

Resources