JavaScript Default Parameters: passing no values - javascript

let add = (a = 0,b = 0) => {
return a+b;
};
console.log(add(5,2));
What I expected was: 0
and the result is: 7
If I pass a = 5 and b = 2 then in the function add, a and b are already assigned 0, so it should return 0. Why 7?

let add = (a = 0,b = 0) => {
return a+b;
};
SO your function will be evaluated something like this
let add = (a, b) => {
a = (typeof(a) !== undefined) ? a : 0;
b = (typeof(b) !== undefined) ? b : 0;
return a + b; //your function code start from here.
}
So if you pass add(5, 2), condition (typeof(a) !== undefined) will be true and 5 will be assign to a and same for b, but if you pass add(5) then condtion for a become ttrue and a is assign as 5 but condition for b is false so b will be assign as 0.

Default parameters are overwritten if provided by the call. Otherwise they would be useless, as you could never change them.

That is the whole point of default values: if you do not provide values when calling the function, the defaults are used, otherwise the values passed in the function call are used.
let add = (a = 2, b = 1) => {
return a + b;
};
console.log(add(5, 2)); // no default will be used
console.log(add(5)); // only second default will be used
console.log(add(undefined, 4)); // only first default will be used

In any language, the default value is only used when there is no other value assigned.
So, whenever you assigned any value to the variable it changes the value.
Same is going with your concept
let add = (a = 0,b = 0) => {
return a+b;
};
console.log(add(5,2)); // it will return 7
console.log(add()); // it will return 0

Related

Why does it return "undefined" instead of the result from the function, i.e one of the console log expressions based on my arguments?

Based on the arguments passed in (10, 20), I would expect it would return "Omg" when invoked. Why do I get "undefined"?
function ifko (a, b) {
const lol = 20;
const result = lol > a + b ? console.log("Super!") : console.log("Omg");
return result;
}
console.log(ifko(10, 20));

Javascript - Passing static value to a callback function

I want to create callback function with some parameters, but I want that one of the values within never change and be set when the function is created!
P.e.
let a = 2;
let y = (b) => { let staticValue = a; return staticValue * b; }
y(1) => 2 -> OK
then
a = 3
y(1) => 3 -> Not OK -> I want the function to have the original value of a.
I know, this happens because the variable a is only evaluated when the function is called. But is there any workaround?
You can accomplish this with what is called an IIFE (immediately invoked function expression)
let a = 2;
const y = (staticValue => b => staticValue * b)(a);
a = 44;
console.log(y(1));
What's happening here is that you have two functions. The first one, staticValue => ... is immediately invoked, and staticValue is given the value of a. Since a is given as an argument of the IIFE, once the function is invoked staticValue won't change, even if the value of a is changed.
The return value of the first function is a second function, b=> ....
let a = 2
let makeY = () => {
let staticValue = a;
return (b)=> staticValue * b;
}
let y = makeY();
or
let a = 2
let y = ((staticValue, b) => {
return staticValue * b;
}).bind(null, a)
you can use closure
function first (a) {
function second (b) {
return a * b;
}
return second;
}
let x = first(2) // the inner function second will close around the variable a which is 2 in this case
console.log(x(3))
let y = first(5) // the inner function second will close around the variable a which is 5 in this case
console.log(y(3))
I think you could apply a Functional programming approach.
const getYFn = (a , b) => {
return a * b;
}
const a = 2
const y = getYFn.bind(null, a);
// the constant y now is a function that partially applied first param
console.log(y(1)); // 2
console.log(y(3)); // 6

JavaScript: create function that accepts callback as input and returns function; Output depends on invoke count

The objective of my code is:
Write a function "once" that accepts a callback as input and returns a function. When the returned function is called the first time, it should call the callback and return that output. If it is called any additional times, instead of calling the callback again it will simply return the output value from the first time it was called.
I tried the code below:
const once = (inputFunc) => {
let invCount = 0;
let firstCallOutput;
return function (num) {
invCount ++;
if (invCount === 1){
firstCallOuput = inputFunc(num);
return inputFunc(num);
}
else {
return firstCallOuput;
}
}
}
const addByTwoOnce = once(function(num) {
return num + 2;
});
// UNCOMMENT THESE TO TEST YOUR WORK!
console.log(addByTwoOnce(5)); //should log 7
console.log(addByTwoOnce(10)); //should log 7
console.log(addByTwoOnce(9001)); //should log 7
My code console logs out the correct values (7) in all three situations. But it fails 2/3 test specs.
What am I doing wrong? How can I pass the two test specs?
Here's a simplified once function -
const once = (f, memo) => x =>
memo === undefined
? (memo = f(x), memo)
: memo
const addTwo = x =>
x + 2
const addTwoOnce =
once(addTwo)
console.log(addTwoOnce(5)) //should log 7
console.log(addTwoOnce(10)) //should log 7
console.log(addTwoOnce(9001)) //should log 7
If you want to safeguard the call site from being able to set the memo, you can make the memo a local variable instead of a parameter -
const once = f =>
{ let memo
return x =>
memo === undefined
? (memo = f(x), memo)
: memo
}
Or maybe you want to safeguard against the potential for the user-supplied function to return undefined. These are all choices you can make with minimal impact on the semantic structure of the code -
const once = f =>
{ let hasRun = false
let memo
return x =>
hasRun
? memo
: (hasRun = true, memo = f(x), memo)
}
Related: constant will return a constant value, regardless of its input -
const constant = x => _ =>
x
const always7 =
constant(7)
console.log(always7(5)) //should log 7
console.log(always7(10)) //should log 7
console.log(always7(9001)) //should log 7
Related: memoise will cache a value for each unique input, only recomputing f if the input has not been seen before -
const memoise = (f, memo = new Map) => x =>
memo.has(x)
? memo.get(x)
: (memo.set(x, f(x)), memo.get(x))
let fib = n =>
n < 2
? n
: fib (n - 1) + fib (n - 2)
console.time("original")
console.log(fib(40))
console.timeEnd("original")
// 1503.43 ms
fib = memoise(fib)
console.time("memoised")
console.log(fib(40))
console.timeEnd("memoised")
// 0.175 ms
Ok,
First we will create a once function that accepts a callback function.
Then we need to create a variable to check if this is the first time or not.
You can make a boolean variable or counter whatever you want. OK,
Then we make a variable result to grap the output of the callback with the initial value of 0
function once(func) {
let isOnce = true
let result = 0
}
OK, after that, let's create a function that will return the callback value if this is the first time, and if not, we will just return the output value from the first time, which we stored to the result
function once(func) {
let isOnce = true
let result = 0
function runOnce(num) {
if(isOnce) {
isOnce = false
result = func(num)
return result
} else {
return result
}
}
}
Finally, we will return the runOnce function.
function once(func) {
let isOnce = true
let result = 0
function runOnce(num) {
if(isOnce) {
isOnce = false
result = func(num)
return result
} else {
return result
}
}
return runOnce
}
Ok, now we need to create a callback function that takes the input and increments it by 2.
function addByTwo(input) {
return input + 2
}
So, time to check
const always7 = once(addByTwo);
console.log(always7(5))
console.log(always7(10))
console.log(always7(9001))
It always runs once and gets the same result every time.
the result is always be 7, click

Javascript chain rule, return specific value instead of [Object object] [x]

The question is at the title, but first please look at this code:
function number(a) {
return {
add: function(b) {
result = a + b;
return this;
}, substract(b) {
result = a - b;
return this;
}
}
These code above are simple example of chain rule. I retun an object so I can do it continuously:
number(2).add(5).add(3 * 12).substract(Math.random());
My problem is, I have to retun an object to keep the function chainable. I'd like to immitate the chain rule, but to return specific value. For instance number(2).add(3) would return 5.
Any suggestion is highly appreciated.
Thanks everyone in advanced.
[x]
One way to make a numeric value like 5 "chainable" is to define a method on the appropriate prototype object, such as Number.prototype. For instance:
Number.prototype.add = function (n) {
return this + n
}
(5).add(2) // 7
5.0.add(2) // 7
5..add(2) // 7
((5).add(2) + 1).add(34) // okay! 42
The syntax above is funny because 5.add(2) is invalid: JavaScript is expecting a number (or "nothing") after 5.. Because this is a global side-effect (it will affect all numbers), care should be taken to avoid unexpected interactions.
The only other Another way to make "5" chain-able is to create a new Number object (5 is not a real Number instance, even though it uses Number.prototype!) and then copy over required methods. (I used to think this was the only other way, but see KooiInc's answer -- however, I am not sure how well-defined returning a non-string from toString is.)
function ops(a) {
return {
add: function(b) {
var res = new Number(a + b) // important!
var op = ops(res)
res.add = op.add // copy over singletons
return res
}
}
}
function number(a) {
return ops(a)
}
number(5).add(2) + 1 // 8
(number(5).add(2) + 1).add(34) // error! add is not a function
However, keep in mind this introduces subtle issues:
typeof 5 // number
typeof new Number(5) // object
5 instanceof Number // false
new Number(5) instanceof Number // true
And this is why we need a Number (search SO for "primitives" in JavaScript):
x = 5
x.foo = "bar"
x.foo // undefined
Furthermore, in conjunction with cwolves' answer, consider:
function number (n) {
if (this === window) { // or perhaps !(this instanceof number)
return new number(n)
} else {
this.value = n
}
}
Then both new number(2) and both number(2) will evaluate to a new number object.
number(2).value // 2
new number(2).value // 2
number(2) instanceof number // true
new number(2) instanceof number // true
Happy coding.
You have two options. You can return new objects:
function number(a){
return this instanceof number ? (this.value = a, this) : new number(a);
}
number.prototype = {
valueOf : function(){
return this.value;
},
add : function(b){
return new number(this.val + b);
},
subtract : function(b){
return new number(this.val - b);
}
};
or you can modify the existing one (mostly the same code as above, this is different):
add : function(b){
this.value += b;
return this;
},
The difference is in how they act:
var x = new number(5),
y = x.add(10);
// with first example
// x == 5, y == 15
// with 2nd example
// x == 15, y == 15, x === y
If you define the value as property (this.a) and use toString within the returned Object, you can chain the methods:
function number(a) {
return {
a: Number(a) || 0, //if not a, or a===NaN, default = 0
add: function(b) {
this.a += b;
return this;
},
subtract: function(b){
this.a -= b;
return this;
},
valueOf: function(){
return Number(this.a);
},
toString: this.valueOf
}
}
var n = number(5);
alert(number.add(5).add(2).subtract(2)); //=> 10
alert(number.add(0.5)); //=> 10.5
alert(number(2).add(5).add(3 * 12).subtract(Math.random());
//=> 42.36072297706966

How can I make var a = add(2)(3); //5 work?

I want to make this syntax possible:
var a = add(2)(3); //5
based on what I read at http://dmitry.baranovskiy.com/post/31797647
I've got no clue how to make it possible.
You need add to be a function that takes an argument and returns a function that takes an argument that adds the argument to add and itself.
var add = function(x) {
return function(y) { return x + y; };
}
function add(x) {
return function(y) {
return x + y;
};
}
Ah, the beauty of JavaScript
This syntax is pretty neat as well
function add(x) {
return function(y) {
if (typeof y !== 'undefined') {
x = x + y;
return arguments.callee;
} else {
return x;
}
};
}
add(1)(2)(3)(); //6
add(1)(1)(1)(1)(1)(1)(); //6
It's about JS curring and a little strict with valueOf:
function add(n){
var addNext = function(x) {
return add(n + x);
};
addNext.valueOf = function() {
return n;
};
return addNext;
}
console.log(add(1)(2)(3)==6);//true
console.log(add(1)(2)(3)(4)==10);//true
It works like a charm with an unlimited adding chain!!
function add(x){
return function(y){
return x+y
}
}
First-class functions and closures do the job.
function add(n) {
sum = n;
const proxy = new Proxy(function a () {}, {
get (obj, key) {
return () => sum;
},
apply (receiver, ...args) {
sum += args[1][0];
return proxy;
},
});
return proxy
}
Works for everything and doesn't need the final () at the end of the function like some other solutions.
console.log(add(1)(2)(3)(10)); // 16
console.log(add(10)(10)); // 20
try this will help you in two ways add(2)(3) and add(2,3)
1.)
function add(a){ return function (b){return a+b;} }
add(2)(3) // 5
2.)
function add(a,b){
var ddd = function (b){return a+b;};
if(typeof b =='undefined'){
return ddd;
}else{
return ddd(b);
}
}
add(2)(3) // 5
add(2,3) // 5
ES6 syntax makes this nice and simple:
const add = (a, b) => a + b;
console.log(add(2, 5));
// output: 7
const add2 = a => b => a + b;
console.log(add2(2)(5));
// output: 7
Arrow functions undoubtedly make it pretty simple to get the required result:
const Sum = a => b => b ? Sum( a + b ) : a;
console.log(Sum(3)(4)(2)(5)()); //14
console.log(Sum(3)(4)(1)()); //8
This is a generalized solution which will solve add(2,3)(), add(2)(3)() or any combination like add(2,1,3)(1)(1)(2,3)(4)(4,1,1)(). Please note that few security checks are not done and it can be optimized further.
function add() {
var total = 0;
function sum(){
if( arguments.length ){
var arr = Array.prototype.slice.call(arguments).sort();
total = total + arrayAdder(arr);
return sum;
}
else{
return total;
}
}
if(arguments.length) {
var arr1 = Array.prototype.slice.call(arguments).sort();
var mytotal = arrayAdder(arr1);
return sum(mytotal);
}else{
return sum();
}
function arrayAdder(arr){
var x = 0;
for (var i = 0; i < arr.length; i++) {
x = x + arr[i];
};
return x;
}
}
add(2,3)(1)(1)(1,2,3)();
This will handle both
add(2,3) // 5
or
add(2)(3) // 5
This is an ES6 curry example...
const add = (a, b) => (b || b === 0) ? a + b : (b) => a + b;
This is concept of currying in JS.
Solution for your question is:
function add(a) {
return function(b) {
return a + b;
};
}
This can be also achieved using arrow function:
let add = a => b => a + b;
solution for add(1)(2)(5)(4)........(n)(); Using Recursion
function add(a) {
return function(b){
return b ? add(a + b) : a;
}
}
Using ES6 Arrow function Syntax:
let add = a => b => b ? add(a + b) : a;
in addition to what's already said, here's a solution with generic currying (based on http://github.com/sstephenson/prototype/blob/master/src/lang/function.js#L180)
Function.prototype.curry = function() {
if (!arguments.length) return this;
var __method = this, args = [].slice.call(arguments, 0);
return function() {
return __method.apply(this, [].concat(
[].slice.call(args, 0),
[].slice.call(arguments, 0)));
}
}
add = function(x) {
return (function (x, y) { return x + y }).curry(x)
}
console.log(add(2)(3))
Concept of CLOSURES can be used in this case.
The function "add" returns another function. The function being returned can access the variable in the parent scope (in this case variable a).
function add(a){
return function(b){
console.log(a + b);
}
}
add(2)(3);
Here is a link to understand closures http://www.w3schools.com/js/js_function_closures.asp
const add = a => b => b ? add(a+b) : a;
console.log(add(1)(2)(3)());
Or (`${a} ${b}`) for strings.
With ES6 spread ... operator and .reduce function. With that variant you will get chaining syntax but last call () is required here because function is always returned:
function add(...args) {
if (!args.length) return 0;
const result = args.reduce((accumulator, value) => accumulator + value, 0);
const sum = (...innerArgs) => {
if (innerArgs.length === 0) return result;
return add(...args, ...innerArgs);
};
return sum;
}
// it's just for fiddle output
document.getElementById('output').innerHTML = `
<br><br>add() === 0: ${add() === 0 ? 'true' : 'false, res=' + add()}
<br><br>add(1)(2)() === 3: ${add(1)(2)() === 3 ? 'true' : 'false, res=' + add(1)(2)()}
<br><br>add(1,2)() === 3: ${add(1,2)() === 3 ? 'true' : 'false, res=' + add(1,2)()}
<br><br>add(1)(1,1)() === 3: ${add(1)(1,1)() === 3 ? 'true' : 'false, res=' + add(1)(1,1)()}
<br><br>add(2,3)(1)(1)(1,2,3)() === 13: ${add(2,3)(1)(1)(1,2,3)() === 13 ? 'true' : 'false, res=' + add(2,3)(1)(1)(1,2,3)()}
`;
<div id='output'></div>
can try this also:
let sum = a => b => b ? sum(a + b) :a
console.log(sum(10)(20)(1)(32)()) //63
const sum = function (...a) {
const getSum = d => {
return d.reduce((i,j)=> i+j, 0);
};
a = getSum(a);
return function (...b) {
if (b.length) {
return sum(a + getSum(b));
}
return a;
}
};
console.log(sum(1)(2)(3)(4,5)(6)(8)())
function add(a, b){
return a && b ? a+b : function(c){return a+c;}
}
console.log(add(2, 3));
console.log(add(2)(3));
This question has motivated so many answers already that my "two pennies worth" will surely not spoil things.
I was amazed by the multitude of approaches and variations that I tried to put "my favourite" features, i. e. the ones that I would like to find in such a currying function together, using some ES6 notation:
const add=(...n)=>{
const vsum=(a,c)=>a+c;
n=n.reduce(vsum,0);
const fn=(...x)=>add(n+x.reduce(vsum,0));
fn.toString=()=>n;
return fn;
}
let w=add(2,1); // = 3
console.log(w()) // 3
console.log(w); // 3
console.log(w(6)(2,3)(4)); // 18
console.log(w(5,3)); // 11
console.log(add(2)-1); // 1
console.log(add()); // 0
console.log(add(5,7,9)(w)); // 24
.as-console-wrapper {max-height:100% !important; top:0%}
Basically, nothing in this recursively programmed function is new. But it does work with all possible combinations of arguments mentioned in any of the answers above and won't need an "empty arguments list" at the end.
You can use as many arguments in as many currying levels you want and the result will be another function that can be reused for the same purpose. I used a little "trick" to also get a numeric value "at the same time": I redefined the .toString() function of the inner function fn! This method will be called by Javascript whenever the function is used without an arguments list and "some value is expected". Technically it is a "hack" as it will not return a string but a number, but it will work in a way that is in most cases the "desired" way. Give it a spin!
Simple Recursion Solution for following use cases
add(); // 0
add(1)(2)(); //3
add(1)(2)(3)(); //6
function add(v1, sum = 0) {
if (!v1) return sum;
sum += v1
return (v2) => add(v2, sum);
}
function add() {
var sum = 0;
function add() {
for (var i=0; i<arguments.length; i++) {
sum += Number(arguments[i]);
}
return add;
}
add.valueOf = function valueOf(){
return parseInt(sum);
};
return add.apply(null,arguments);
}
// ...
console.log(add() + 0); // 0
console.log(add(1) + 0);/* // 1
console.log(add(1,2) + 0); // 3
function A(a){
return function B(b){
return a+b;
}
}
I found a nice explanation for this type of method. It is known as Syntax of Closures
please refer this link
Syntax of Closures
Simply we can write a function like this
function sum(x){
return function(y){
return function(z){
return x+y+z;
}
}
}
sum(2)(3)(4)//Output->9
Don't be complicated.
var add = (a)=>(b)=> b ? add(a+b) : a;
console.log(add(2)(3)()); // Output:5
it will work in the latest javascript (ES6), this is a recursion function.
Here we use concept of closure where all the functions called inside main function iter refer and udpate x as they have closure over it. no matter how long the loop goes , till last function , have access to x.
function iter(x){
return function innfunc(y){
//if y is not undefined
if(y){
//closure over ancestor's x
x = y+x;
return innfunc;
}
else{
//closure over ancestor's x
return x;
}
}
}
iter(2)(3)(4)() //9
iter(1)(3)(4)(5)() //13
let multi = (a)=>{
return (b)=>{
return (c)=>{
return a*b*c
}
}
}
multi (2)(3)(4) //24
let multi = (a)=> (b)=> (c)=> a*b*c;
multi (2)(3)(4) //24
we can do this work using closure.
function add(param1){
return function add1(param2){
return param2 = param1 + param2;
}
}
console.log(add(2)(3));//5
I came up with nice solution with closure, inner function have access to parent function's parameter access and store in its lexical scope, when ever we execute it, will get answer
const Sum = function (a) {
return function (b) {
return b ? Sum(a + b) : a;
}
};
Sum(1)(2)(3)(4)(5)(6)(7)() // result is 28
Sum(3)(4)(5)() // result is 12
Sum(12)(10)(20) // result is 42
enter image description here
You should go in for currying to call the function in the above format.
Ideally, a function which adds two numbers will be like,
let sum = function(a, b) {
return a + b;
}
The same function can be transformed as,
let sum = function(a) {
return function(b) {
return a+b;
}
}
console.log(sum(2)(3));
Let us understand how this works.
When you invoke sum(2), it returns
function(b) {
return 2 + b;
}
when the returned function is further invoked with 3, b takes the value 3. The result 5 is returned.
More Detailed Explanation:
let sum = function(a) {
return function(b) {
return a + b;
}
}
let func1 = sum(2);
console.log(func1);
let func2 = func1(3)
console.log(func2);
//the same result can be obtained in a single line
let func3 = sum(2)(3);
console.log(func3);
//try comparing the three functions and you will get more clarity.
This is a short solution:
const add = a => b => {
if(!b) return a;
return add(a + b);
}
add(1)(2)(3)() // 6
add(1)(2)(3)(4)(5)() // 15

Categories

Resources