How can I declare optional function parameters in JavaScript? [duplicate] - javascript

This question already has answers here:
Is there a better way to do optional function parameters in JavaScript? [duplicate]
(28 answers)
Closed 3 years ago.
Can I declare default parameter like
function myFunc( a, b=0)
{
// b is my optional parameter
}
in JavaScript?

With ES6: This is now part of the language:
function myFunc(a, b = 0) {
// function body
}
Please keep in mind that ES6 checks the values against undefined and not against truthy-ness (so only real undefined values get the default value - falsy values like null will not default).
With ES5:
function myFunc(a,b) {
b = b || 0;
// b will be set either to b or to 0.
}
This works as long as all values you explicitly pass in are truthy.
Values that are not truthy as per MiniGod's comment: null, undefined, 0, false, ''
It's pretty common to see JavaScript libraries to do a bunch of checks on optional inputs before the function actually starts.

Update
With ES6, this is possible in exactly the manner you have described; a detailed description can be found in the documentation.
Old answer
Default parameters in JavaScript can be implemented in mainly two ways:
function myfunc(a, b)
{
// use this if you specifically want to know if b was passed
if (b === undefined) {
// b was not passed
}
// use this if you know that a truthy value comparison will be enough
if (b) {
// b was passed and has truthy value
} else {
// b was not passed or has falsy value
}
// use this to set b to a default value (using truthy comparison)
b = b || "default value";
}
The expression b || "default value" evaluates the value AND existence of b and returns the value of "default value" if b either doesn't exist or is falsy.
Alternative declaration:
function myfunc(a)
{
var b;
// use this to determine whether b was passed or not
if (arguments.length == 1) {
// b was not passed
} else {
b = arguments[1]; // take second argument
}
}
The special "array" arguments is available inside the function; it contains all the arguments, starting from index 0 to N - 1 (where N is the number of arguments passed).
This is typically used to support an unknown number of optional parameters (of the same type); however, stating the expected arguments is preferred!
Further considerations
Although undefined is not writable since ES5, some browsers are known to not enforce this. There are two alternatives you could use if you're worried about this:
b === void 0;
typeof b === 'undefined'; // also works for undeclared variables

Related

How to get the underscore function _.first to work on the arguments objects?

As part of the precourse for a coding bootcamp, we have to create a simpler version of the underscore JS library. I am struggling with creating the _.first function, which:
Returns an array with the first n elements of an array.
If n is not provided it returns an array with just the first element.
This is what I've got so far:
_.first = function(array, n) {
if (!Array.isArray(array)) return [];
if (typeof n != "number" || n <= 0) return [].slice.call(array, 0, 1);
return n >= array.length ? array : [].slice.call(array, 0, n);
};
It passes all test except one: "It must work on an arguments object"
I know the arguments object passes an array with all the arguments passed and it has a length property but Im struggling to work with it.
Any help would be much appreciated.
The arguments object is just that, a variable defined implicitly on each function scope that acts like an array. Has a length property and you can access the elements by using number properties like a normal array:
var _ = {};
_.first = function() {
if (arguments.length == 0) { // If there's no arguments
return [];
} else { // When there's 1 or more arguments
var array = arguments[0];
var n = arguments.length > 1 ? arguments[1] : 1; // If there's only the "array" argument ("n" is not provided), set "n" to 1
// And now your code, which has nice checks just in case the values are invalid
if (!Array.isArray(array)) {
return [];
}
if (typeof n != "number" || n <= 0) {
n = 1;
}
return [].slice.call(array, 0, n); // Don't worry if slice is bigger than the array length. It will just work, and also always return a copy of the array instead of the array itself.
}
};
console.log( _.first() );
console.log( _.first([0,1,2]) );
console.log( _.first([0,1,2], 2) );
console.log( _.first([0,1,2], 10) );
I would add something to the first answer. The arguments object is something that is normally created implicitly by JavaScript and made available inside the function body. In order to write a unit test for "It must work on an arguments object", they must explicitly define an arguments object and pass it in. This is a bad unit test because it is testing the internal working of your function. You should be free to write the function any way you like, and a unit test should test the external behaviour of the function (return value and/or side effects, based on the arguments passed).
So imo your original solution is good and the test is designed to force you to use a certain syntax for the sake of learning, but this is misleading.

Why is (null==undefined) true in JavaScript? [duplicate]

How do I check a variable if it's null or undefined and what is the difference between the null and undefined?
What is the difference between == and === (it's hard to search Google for "===" )?
How do I check a variable if it's null or undefined...
Is the variable null:
if (a === null)
// or
if (a == null) // but see note below
...but note the latter will also be true if a is undefined.
Is it undefined:
if (typeof a === "undefined")
// or
if (a === undefined)
// or
if (a == undefined) // but see note below
...but again, note that the last one is vague; it will also be true if a is null.
Now, despite the above, the usual way to check for those is to use the fact that they're falsey:
if (!a) {
// `a` is falsey, which includes `undefined` and `null`
// (and `""`, and `0`, and `NaN`, and [of course] `false`)
}
This is defined by ToBoolean in the spec.
...and what is the difference between the null and undefined?
They're both values usually used to indicate the absence of something. undefined is the more generic one, used as the default value of variables until they're assigned some other value, as the value of function arguments that weren't provided when the function was called, and as the value you get when you ask an object for a property it doesn't have. But it can also be explicitly used in all of those situations. (There's a difference between an object not having a property, and having the property with the value undefined; there's a difference between calling a function with the value undefined for an argument, and leaving that argument off entirely.)
null is slightly more specific than undefined: It's a blank object reference. JavaScript is loosely typed, of course, but not all of the things JavaScript interacts with are loosely typed. If an API like the DOM in browsers needs an object reference that's blank, we use null, not undefined. And similarly, the DOM's getElementById operation returns an object reference — either a valid one (if it found the DOM element), or null (if it didn't).
Interestingly (or not), they're their own types. Which is to say, null is the only value in the Null type, and undefined is the only value in the Undefined type.
What is the difference between "==" and "==="
The only difference between them is that == will do type coercion to try to get the values to match, and === won't. So for instance "1" == 1 is true, because "1" coerces to 1. But "1" === 1 is false, because the types don't match. ("1" !== 1 is true.) The first (real) step of === is "Are the types of the operands the same?" and if the answer is "no", the result is false. If the types are the same, it does exactly what == does.
Type coercion uses quite complex rules and can have surprising results (for instance, "" == 0 is true).
More in the spec:
Abstract Equality Comparison (==, also called "loose" equality)
Strict Equality Comparison (===)
The difference is subtle.
In JavaScript an undefined variable is a variable that as never been declared, or never assigned a value. Let's say you declare var a; for instance, then a will be undefined, because it was never assigned any value.
But if you then assign a = null; then a will now be null. In JavaScript null is an object (try typeof null in a JavaScript console if you don't believe me), which means that null is a value (in fact even undefined is a value).
Example:
var a;
typeof a; # => "undefined"
a = null;
typeof null; # => "object"
This can prove useful in function arguments. You may want to have a default value, but consider null to be acceptable. In which case you may do:
function doSomething(first, second, optional) {
if (typeof optional === "undefined") {
optional = "three";
}
// do something
}
If you omit the optional parameter doSomething(1, 2) thenoptional will be the "three" string but if you pass doSomething(1, 2, null) then optional will be null.
As for the equal == and strictly equal === comparators, the first one is weakly type, while strictly equal also checks for the type of values. That means that 0 == "0" will return true; while 0 === "0" will return false, because a number is not a string.
You may use those operators to check between undefined an null. For example:
null === null # => true
undefined === undefined # => true
undefined === null # => false
undefined == null # => true
The last case is interesting, because it allows you to check if a variable is either undefined or null and nothing else:
function test(val) {
return val == null;
}
test(null); # => true
test(undefined); # => true
The spec is the place to go for full answers to these questions. Here's a summary:
For a variable x, you can:
check whether it's null by direct comparison using ===. Example: x === null
check whether it's undefined by either of two basic methods: direct comparison with undefined or typeof. For various reasons, I prefer typeof x === "undefined".
check whether it's one of null and undefined by using == and relying on the slightly arcane type coercion rules that mean x == null does exactly what you want.
The basic difference between == and === is that if the operands are of different types, === will always return false while == will convert one or both operands into the same type using rules that lead to some slightly unintuitive behaviour. If the operands are of the same type (e.g. both are strings, such as in the typeof comparison above), == and === will behave exactly the same.
More reading:
Angus Croll's Truth, Equality and JavaScript
Andrea Giammarchi's JavaScript Coercion Demystified
comp.lang.javascript FAQs: JavaScript Type-Conversion
How do I check a variable if it's null or undefined
just check if a variable has a valid value like this :
if(variable)
it will return true if variable does't contain :
null
undefined
0
false
"" (an empty string)
NaN
undefined
It means the variable is not yet intialized .
Example :
var x;
if(x){ //you can check like this
//code.
}
equals(==)
It only check value is equals not datatype .
Example :
var x = true;
var y = new Boolean(true);
x == y ; //returns true
Because it checks only value .
Strict Equals(===)
Checks the value and datatype should be same .
Example :
var x = true;
var y = new Boolean(true);
x===y; //returns false.
Because it checks the datatype x is a primitive type and y is a boolean object .
Ad 1. null is not an identifier for a property of the global object, like undefined can be
let x; // undefined
let y=null; // null
let z=3; // has value
// 'w' // is undeclared
if(!x) console.log('x is null or undefined');
if(!y) console.log('y is null or undefined');
if(!z) console.log('z is null or undefined');
try { if(w) 0 } catch(e) { console.log('w is undeclared') }
// typeof not throw exception for undelared variabels
if(typeof w === 'undefined') console.log('w is undefined');
Ad 2. The === check values and types. The == dont require same types and made implicit conversion before comparison (using .valueOf() and .toString()). Here you have all (src):
if
== (its negation !=)
=== (its negation !==)
If your (logical) check is for a negation (!) and you want to capture both JS null and undefined (as different Browsers will give you different results) you would use the less restrictive comparison:
e.g.:
var ItemID = Item.get_id();
if (ItemID != null)
{
//do stuff
}
This will capture both null and undefined
Try With Different Logic. You can use bellow code for check all four(4) condition for validation like not null, not blank, not undefined and not zero only use this code (!(!(variable))) in javascript and jquery.
function myFunction() {
var data; //The Values can be like as null, blank, undefined, zero you can test
if(!(!(data)))
{
//If data has valid value
alert("data "+data);
}
else
{
//If data has null, blank, undefined, zero etc.
alert("data is "+data);
}
}

When is toString() get called implicitly in javascript?

With reference to below code written in Javascript.
let a = {
value: 2,
toString: function() {
return ++this.value;
}
}
if (a == 3 && a == 4) {
console.log('Condition is true');
}
The output is "Condition is true". Looks like it invokes toString() function. But how?
When I replace "==" with "===", condition does not evaluates to true and it does not invoke toString() function this time?
Can someone explain me in detail what's going under the hood?
When you do == it is not a strict comparison so what it does for the condition a == 3 && a == 4, is that first it compares a == 3. Since, it is not a strict comparison, it will change a to string. And since you have toString() in a, that will increment the value of a from 2 to 3 and hence a == 3 result in true. Then, a == 4 checks the same way and this time the value of a is 3 so when it checks for a == 4 it results in true by invoking the toString() function of a.
let a = {
value: 2,
toString: function() {
return ++this.value;
}
}
if (a == 3 && a == 4) {
console.log('Condition is true');
}
However, when you use ===, it works as a strict comparison and the type of LHS should match RHS. Thus, a is a object in LHS and there is a number type in RHS, so it results false for a == 3 and hence, a == 3 && a == 4
let a = {
value: 2,
toString: function() {
return ++this.value;
}
}
if (a === 3 && a === 4) {
console.log('Condition is true');
} else {
console.log('Condition is false');
}
The output is "Condition is true". Looks like it invokes 'toString()'
function.
Everytime you use == operator between two variables with different types it is invoked internally toString method which will coerce one member. Have a look at type coercion
But how?
You're creating a custom toString function for your a object that changes what it returns each time it is used such that it satisfies all two conditions.
You can also use valueOf method.
How about === operator ?
Otherwise, the === operator will not do the conversion.
What means this ?
If you're using === operator with two values with different type === will simply return false.
Happen to notice that toString is invoked in interpolated string, executed prioritized than valueOf
var a = {
value: 1000,
toString: () => 'call toString method',
valueOf: () => 'call valueOf method'
};
console.log(`interpreted value: ${a}`); // interpreted value: call toString method
In addition to Mihai's answer, === is a strict typechecking equality operator which checks for the type of the operands and the values as well.
In your case, the type of a is an object, whereas 3 and 4 are numbers. So the condition doesn't evaluate to true.
it checks whether object has falsy value or not when you use == thats why you get true from a == 4 and a == 3. Have a look at type coercion. It does not coerce variables when comparing them and thats why you cannot get into the block statement
You can find detail information of how '==' and '===' works in javascript from link below:
Equality comparisons and sameness
In this URL refer 'Loose equality using ==' section.
In you case your comparison as a == 3. a is object and 3 is number. So comparison will take place as ToPrimitive(a) == 3. What ToPrimitive(a) do is it attempting to invoke varying sequences of a.toString and a.valueOf methods on A. This is how your toString function is called.
On the surface your question looks like the sheer difference between == and === operators, but in fact there is bit more to it.
For your first question, since javascript is not strictly typed language, there is 2 operators, == will try to convert the left operand to right ones type if possible whereas === will give false if the types are different with the exception of NaN.
A more interesting question is when toString method gets called. Normally when you create an object, either by typing an object literal or through a constructor, it will inherit toString from the Object, you easily check this:
var u = function(){};
var w = {};
u.prototype.toString === Object.prototype.toString //true
w.toString === Object.prototype.toString //true as well
Now what you might forget is that there is also a valueOf method:
u.prototype.valueOf === Object.prototype.valueOf //true
w.valueOf === Object.prototype.valueOf //true as well
But what does it do? I points to itself:
w.valueOf === w //true
u.prototype.valueOf() === u.prototype //true as well
So when an object is given, the first choice is to use the toString becuae valueOf will result in the object itself. What does toString give by default? it can depend on what is there on its prototype chain:
w.toString() //"[object Object]"
u.toString() //"function (){}"
u.prototype.toString.call(u) //"[object Function]"
So by default the first choice is to use the nearest toString method of the object. Now to see what happens if we override BOTH valueOf and toString, let me construct this object:
var x = {
inner:10,
ledger:[],
result:[],
timeout:0,
toString:function(){
console.log("String");
clearTimeout(this.timeout);
this.timeout = setTimeout((function(){
this.result = this.ledger;
this.ledger = []}).bind(this)
,0) ;
this.ledger.push("toString");
this.ledger.slice(-2);
return String(this.inner);
},
valueOf:function(){
console.log("Valueof");
clearTimeout(this.timeout);
this.timeout = setTimeout((function(){
this.result = this.ledger;
this.ledger = []}).bind(this)
,0) ;
this.ledger.push("valueOf");
this.ledger.slice(-2);
return this.inner;
}
}
This object will keep a "ledger", an array of valueOf or toString or both called during type conversion. It will also console.log. So,here are some operations that will trigger type conversion just like ==:
+x //10
//ValueOf
"5" + x //"510"
//ValueOf
x + [] //10
//ValueOf
x + "str"//"10str"
//ValueOf
x.toString() //"10"
//String
String(x) //"10"
//String
x + {u:""} //"10[object Object]"
//valueOf
So in many cases if a non-default valueOf is found that is used. If the right operand is a string, then the returned value from valueOf is converted to string rather than toString on the object. To override default behavior you can force call to string by using toString or String( as shown in the examples. So the priority list goes as:
Custom valueOf >> custom toString >> default toString >>>> default valueOf

What is the reason that the OR operator is in this function?

I read the following code but I can not understand what it means "||" in this context:
function factorial(numero) {
numero = numero || 1
return numero * factorial(numero - 1)
}
I understand the logical operators but I do not find the sense to call the function if you pass any argument. That is why the reason for my question.
That's called short-circuiting. || is the OR operator, but the way it is evaluated, it will look at the left side (and never look at the right side, thus "short-circuiting".
If it is true, it will use that value. If it is false, it will use the right side. Here, if 'numero' is undefined, it will be false, and therefore the placeholder default value of 1 will be used.
It is like a fallback. If numero is a falsy value (false, '', undefined, null, NaN, 0) it will set the value to 1.
As we can see here in these two tests, if a values is not passed it will use the fallback otherwise it will use the value passed as a parameter.
function test(value) {
console.log(value || 'Not Set')
}
test()
test('Awesome')
There are also more advanced ways which work differently but also produce the similar effect. Here we can do the complete opposite by using && instead which will only run the next item if the previous command is truthy.
let items = []
function addItem(a) {
let contains = items.includes(a)
!contains && items.push(a)
}
addItem('cat')
addItem('dog')
addItem('pig')
addItem('cat')
addItem('cat')
console.log(items)
In the above we use && instead which will do the exact opposite of ||, so if contains is true, we run the next command, otherwise end the current statement.
Lastly, we can combine the two and get a whole new result:
let items = []
function addItem(a) {
let contains = items.includes(a)
!contains && a % 2 == 0 && items.push(a) || console.log('Item', a, 'is not valid')
}
addItem(1)
addItem(2)
addItem(10)
addItem(15)
addItem(10)
addItem(100)
addItem(102)
addItem(103)
console.log(items)
And with this example we only insert items into the array if they are not already in the array and are an even number. otherwise we will output that the value isn't a valid insert either because it was already in the array, or it wasn't event.
It means or it always means or in JavaScript. What that statement does is to set numero to the current value of numero if it is a truthy value or 1 if it is not.
The new syntax, allows you to do this:
function factorial(numero = 1) {
....
}
Which is more convenient for setting default values to parameters.
In Javascript, but also in other languages, the operator || is defined as:
Logical OR (||) expr1 || expr2 Returns expr1 if it can be converted to true; otherwise, returns expr2. Thus, when used with Boolean values, || returns true if either operand is true.
(https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Operators/Logical_Operators)
That snippet is a shorthand for:
if (!numero)
numero = 1;
So, if numero is a falsey value (0, Nan, null, undefined or an empty string) it will be set at 1.
It only expands the second branch If In your case parameter is not given , as mentioned above It is called Short circuit evaluations.
Treat it like IF numero was passed assign it to variable ELSE set variable to 1

Extending the logical OR || syntax for the empty array

Let f and g be two function. Then f() || g() first evaluates f. If the return value of f is falsy it then evaluates g, and returns g's return value.
I love the neat and concise syntax, but it doesn't include the case where f returns the empty array [], which I want to consider "falsy".
Is there clean way of having this syntax for [] instead of the traditional falsy values?
You could write a function that converts the empty array into a real falsy value, maybe?
function e(a) { return a instanceof Array ? (a.length ? a : false) : a; }
var result = e(f()) || g();
The problem with the other solutions presented is that it doesn't behave exactly how you may want the short-circuiting to work. For example, converting the value of f() to a truthy value before the || operator means you lose the ability of returning the result of f(). So here's my preferred solution: write a function that behaves like the || operator.
// let's call the function "either" so that we can read it as "either f or g"
function either () {
var item;
// return the first non-empty truthy value or continue:
for (var i=0;i<arguments.length;i++) {
item = arguments[i];
if (item.length === 0 || !item) continue
return item;
}
return false;
}
We can now use the either() function like how we would the || operator:
either(f(), g());
Why not simply do the length check at f()?
function f(){
var returned_array = new Array();
...
if(!returned_array.length)
return false;
}
If you're talking about actually overloading the || operator, you cannot do that in JavaScript (it was proposed back in ECMAScript 4 but rejected). If you really want to do operator overloading in JavaScript, you'd have to use something like JavaScript Shaper, which is "an extensible framework for JavaScript syntax tree shaping" - you could actually use this to overload operators.

Categories

Resources