This question already has answers here:
Set a default parameter value for a JavaScript function
(29 answers)
Closed 2 years ago.
In C# you can do something like that:
class Program
{
static void Main(string[] args)
{
Sum(2, 2, d: 10);
}
static int Sum(int a, int b, int c = 0, int d = 0)
{
return a + b + c + d;
}
}
Is there a way to do something similar with Javascript?
const foo = (a, b, c = 0, d = 0) => a + b + c + d;
And then call this function:
foo(2, 2, d = 10);
Or the only way is call this function this way?
foo(2, 2, undefined, 10);
Yes you can do default parameters in JavaScript however there is no support for named parameters. So the arguments must follow the same order as parameters.
The javascript alternative is object destructuring:
const foo = ({a, b, c = 0, d = 0}) => a + b + c + d;
Which you can then call "out of order" with:
foo({b: 1, a: 2, d: 6})
With ES6, you can do something like this:
const hello = (name = 'John Doe', b) => {
console.log(`Hello Mr ${name}`);
};
hello('Jagathish'); // Hello Mr Jagathish
hello(); // Hello Mr John Doe
When I pass an array and Object respectively to function.apply(), I get the o/p of NaN but when I do it Object and array, I get a Number. Why is this happening?
since arrays are also considered as objects, why I'm unable to use this to represent array from the same context/
I've tried changing the position of variable calling but I know for a fact that the order only matters when it's a parameter.
function add() {
return arr[0] + arr[1] + this.a + this.b;
}
let obj = {
a: 1,
b: 2
};
let arr = [1, 2];
console.log(add.apply(arr, obj));
console.log(add.apply(obj, arr));
O/P
NaN
6
Perhaps a diagram could help. Your function uses no parameters, so what you supply in the second argument to apply (which should be an array of values) doesn't matter. Only the first parameter (which becomes this in the function body) matters.
When you call with arr, then this points to the arr supplied in the argument, but arr also points to the same object, as it's global and not overwritten anywhere:
function add() {
// 1 + 1 + undefined + undefined //=> NaN
return arr[0] + arr[1] + this.a + this.b;
} // | | | |
// +------+--------+---------+-----------+
// |
// V
let arr = [1, 2]; let obj = {a: 1, b: 2};
// ^
// `-----Nothing points to this
add.apply(arr) // equivalent to `add.apply(arr, obj)`, since `add` ignores parameters
When you call with obj, then this points to the obj supplied in the argument, and arr again points to the global arr object:
function add() {
// 1 + 2 + 1 + 2 //=> 6
return arr[0] + arr[1] + this.a + this.b;
} // | | | |
// +------+--------+ +-----------+
// | |
// V V
let arr = [1, 2]; let obj = {a: 1, b: 2};
add.apply(obj) // equivalent to `add.apply(obj, arr)`, since `add` ignores parameters
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
function.apply(thisArg, [argsArray]) your first argument becomes this in the function, and second argument is an array of arguments youre passing to the function
so add.apply(arr, obj) really should be add.apply(arr, [obj]) would translate to the following, which this(arr) doesnt have properties a nor b
function add() {
return arr[0] + arr[1] + arr.a + arr.b;
}
// then invoking it as
add(obj);
and add.apply(obj, arr) would translate to
function add() {
return arr[0] + arr[1] + obj.a + obj.b;
}
// them invoking it as
add(1, 2);
I am calling a function at several places within my app. This function takes several parameters whose values might change. To avoid re-typing, I want to save a reference to this function so that I can simply call this referred function everywhere. Here is the simplified code:
const func1 = (a,b,c) => a + b + c;
let a = 1, b = 2, c = 3;
const func2 = func1.bind(this, a, b, c);
func2();
//prints 6
c = 6;
func2();
//still prints 6!
How can I ge func1 to be executed with updated values of a, b and c by calling func2?
Use arrow function:
const func1 = (a,b,c) => a + b + c;
let a = 1, b = 2, c = 3;
const func2 = () => func1(a, b, c);
console.log(func2());
c = 6;
console.log(func2());
You can bind the function to an array of [a, b, c] instead, and then change the property at index 2:
const func1 = (a,b,c) => a + b + c;
const params = [1, 2, 3];
const func2 = () => func1(...params);
func2();
params[2] = 6;
func2();
If you only change c, you could consider binding the function to a and b, and then passing the changing c:
const func1 = (a,b,c) => a + b + c;
const params = [1, 2];
const func2 = (c) => func1(...params, c);
func2(3);
func2(6);
If you want to use params from scope where you declare your function, just skip those params in function signature
const f = () => a + b + c;
let a = 1, b = 2, c = 3;
console.log(f());
c = 6;
console.log(f());
Instead of this const func2 = func1.bind(this, a, b, c);
You can use this function(arrow): const func2 = () => func1(a, b, c);
In many functions I have noticed the following pattern: function declares variables, combines it to the result and returns result. It is shown in this very simple example:
function fn() {
var a = 1,
b = 2;
return a + b;
}
fn(); // 3
or:
function fn() {
var a, b;
return a = 1,
b = 2,
a + b;
}
fn(); // 3
I would like to minimize this code and reduce it to the one statement. It could look like this:
function fn() {
return a = 1,
b = 2,
a + b;
}
However this code declares variables a, b in global scope which is not acceptable. Is it possible to do this in javascript?
Maybe this works for you, which is not advisable because of using assignment alogn with the comma operator.
function fn(a, b) { // declaration in local scope
return a = 1, b = 2, a + b; // return value with comma operator
}
A newer approach takes default values and returns just the addition of both.
fn = (a = 1, b = 2) => a + b;
What you are trying to do (declare using var and return in same statement) is not possible with JavaScript syntax.
The most concise you can get is your first option:
function fn() {
var a = 1,
b = 2;
return a + b;
}
fn(); // 3
I have this two variables:
var a = 1,
b = 2;
My question is how to swap them? Only this variables, not any objects.
Here's a one-liner to swap the values of two variables.
Given variables a and b:
b = [a, a = b][0];
Demonstration below:
var a=1,
b=2,
output=document.getElementById('output');
output.innerHTML="<p>Original: "+a+", "+b+"</p>";
// swap values for variables "a" and "b"
b = [a, a = b][0];
output.innerHTML+="<p>Swapped: "+a+", "+b+"</p>";
<div id="output"></div>
ES6 (Firefox and Chrome already support it (Destructuring Assignment
Array Matching)):
let a = 5, b = 6;
[a, b] = [b, a];
console.log(`${a} ${b}`);
You can do this:
var a = 1,
b = 2,
tmp;
tmp = a;
a = b;
b = tmp;
For readability and maintainability, this can't be beat (at least in JavaScript). Anybody maintaining the code (including you six months from now) will know exactly what's going on.
Since these are integers, you can also use any number of clever tricks1 to swap without using a third variable. For instance you can use the bitwise xor operator:
let a = 1, b = 2;
a = a ^ b;
b = a ^ b;
a = a ^ b;
console.log('a is now:', a);
console.log('b is now:', b);
This is called the XOR swap algorithm. Its theory of operation is described in this Wikipedia article.
1"The competent programmer is fully aware of the limited size of his own skull. He therefore approaches his task with full humility, and avoids clever tricks like the plague." — Edsger W. Dijkstra
Don't use the code below. It is not the recommended way to swap the values of two variables (simply use a temporary variable for that). It just shows a JavaScript trick.
This solution uses no temporary variables, no arrays, only one addition, and it's fast.
In fact, it is sometimes faster than a temporary variable on several platforms.
It works for all numbers, never overflows, and handles edge-cases such as Infinity and NaN.
a = b + (b=a, 0)
It works in two steps:
(b=a, 0) sets b to the old value of a and yields 0
a = b + 0 sets a to the old value of b
Since ES6, you can also swap variables more elegantly:
var a = 1,
b = 2;
[a, b] = [b, a];
console.log('a:', a, 'b:', b); // a: 2 b: 1
You can now finally do:
let a = 5;
let b = 10;
[a, b] = [b, a]; // ES6
console.log(a, b);
Here's a one-liner, assuming a and b exist already and have values needing to be swapped:
var c=a, a=b, b=c;
As #Kay mentioned, this actually performs better than the array way (almost 2x as fast).
You could use a temporary swap variable or XOR.
a = a ^ b
b = a ^ b
a = a ^ b
This is just a basic logical concept and works in every language that supports XOR operation.
edit: see the Comments. Forgot to tell that this works for sure only with integer. Assumed the integer variables from question's thread
Use a third variable like this:
var a = 1,
b = 2,
c = a;
a = b; // must be first or a and b end up being both 1
b = c;
DEMO - Using a third variable
As your question was precious "Only this variables, not any objects. ", the answer will be also precious:
var a = 1,
b = 2
a=a+b;
b=a-b;
a=a-b;
it's a trick
And as Rodrigo Assis said, it "can be shorter "
b=a+(a=b)-b;
Demo:
http://jsfiddle.net/abdennour/2jJQ2/
ES6 Destructuring:
Using an array: [a, b] = [b, a]; // my favorite
Using an object: {a, b} = {a:b, b:a}; // not bad neither
How could we miss these classic oneliners
var a = 1, b = 2
a = ({a:b, _:(b=a)}).a;
And
var a = 1, b = 2
a = (_=b,b=a,_);
The last one exposes global variable '_' but that should not matter as typical javascript convention is to use it as 'dont care' variable.
I see kind of programming olympiad here. One more tricky one-line solution:
b = (function(){ a=b; return arguments[0]; })(a);
Fiddle: http://jsfiddle.net/cherniv/4q226/
Single line swapping
a = a^b^(b^=(a^b));
var a = 5;
var b = 10;
b = [a, a = b][0];
//or
b = [a, a = b];
b = b[0];
//or
b = [a, b];
a = b[1];
b = b[0];
alert("a=" + a + ',' + "b=" + b);
remove or comment the 2 //or's and run with the one set of code
http://jsfiddle.net/USdv8/57/
We are able to swap var like this :
var val1 = 117,
val2 = 327;
val2 = val1-val2;
console.log(val2);
val1 = val1-val2;
console.log(val1);
val2 = val1+val2;
console.log(val2);
first way,
var a = 5, b = 9;
a = a - b;
b = a + b;
a = b - a;
console.log(a, b);
second way
var a = 19, b = 22;
[a, b] = [b, a];
console.log(a, b);
simple and clear answer.
Because I hear this method runs slower:
b = [a, a = b][0];
If you plan on storing your vars in an object (or array), this function should work:
function swapVars(obj, var1, var2){
let temp = obj[var1];
obj[var1] = obj[var2];
obj[var2] = temp;
}
Usage:
let test = {a: 'test 1', b: 'test 2'};
console.log(test); //output: {a: 'test 1', b: 'test 2'}
swapVars(test, 'a', 'b');
console.log(test); //output: {a: 'test 2', b: 'test 1'}
We can use the IIFE to swap two value without extra parameter
var a = 5, b =8;
b = (function(a){
return a
}(a, a=b));
document.write("a: " + a+ " b: "+ b);
Till ES5, to swap two numbers, you have to create a temp variable and then swap it.
But in ES6, its very easy to swap two numbers using array destructuring. See example.
let x,y;
[x,y]=[2,3];
console.log(x,y); // return 2,3
[x,y]=[y,x];
console.log(x,y); // return 3,2
Know more about JavaScript ES6 destructuring
Although the same answer is given previously, but here is a png to describe it.
Simplest form possible:
let a = 2, b = 4;
[b, a] = [a, b];
a more verbose approach would be
let a = 2, b = 4;
a = [a, b];
b = a[0];
a = a[1];