As a beginner in Javascript, I am trying to call a function whose parameter is a function.But I get this error.
function execute(f) {
f();
}
var m = function(x) { return x * x };
m(8) #=> returns 64
execute(m(8)) #=> Uncaught TypeError: number is not a function
I guess function execute is executing m(8) before exercising its body, therefore the call becomes execute(64). If so, how do I go about passing a function with a parameter?
You'll have to pass them as separate parameters and use call or apply.
For example :
function execute(f, args) {
return f.apply(null, args);
}
var m = function(x) { return x * x };
m(8)
execute(m, [8])
Now, let's suppose you want to have functions taking any number of arguments, and you don't want to bother with making an array. Then it's a little more fun :
function execute() {
return arguments[0].apply(null, [].slice.call(arguments, 1));
}
var m = function(x,y) { return x * y };
console.log(m(8, 4))
console.log(execute(m, 8, 4))
You can use bind to partially apply 8 to m:
function execute(f) {
f();
}
var m = function(x) { return x * x };
execute(m.bind(null, 8))
Related
Is this possible in JavaScript
I am curious, if I set up three parameters in one function, can I pass the arguments independently in three different functions?
For example, if I created a function that calculates three parameters like the one below, can I then just pass an argument for each of these parameters x, y and z in three different functions.
I understand the example code is not a very good example but its the only way I could think up a explanation.
Main function
function mathsCal(x, y, z) {
return (x * y) - z;
}
The three independent functions
function one(x) {
return x = 23;
}
function two(y) {
return x = 19;
}
function three(z) {
return x = 45;
}
You can do something like this for example you have your 3 functions, each of them receive 1 parameter
function num1(param) {
//your code for num1, return a value
return param
}
function num2(param) {
//your code for num2, return a value
return param
}
function num3(param) {
//your code for num3, return a value
return param
}
Then you can call them all inside single function that will receive all 3 parameters needed for num1, num2 and num3
function sumNum(x, y, z) {
var value1 = num1(x);
var value2 = num1(y);
var value3 = num1(z);
return (value1 * value2) + value3;
}
Then call your function with the needed parameters
var result = sumNum(1,2,3)
console.log(result);//your output = 5
Without using JQuery and using the code I got from user "Chris G", I believe this is the best answer to my question. Please leave comments if I have written this wrong so I can correct it.
<button id= "btn">Get Answer</button>
var numVal1 = 2;
var numVal2 = 6;
var numVal3 = 9;
document.getElementById("btn").addEventListener("click", function() {
funcPara(numVal1, numVal2, numVal3);
})
function funcPara(x, y, z) {
num1(x);
num2(y);
num3(z);
}
function num1(para) {
console.log(`num1 = ${para}`);
}
function num2(para) {
console.log(`num2 = ${para}`);
}
function num3(para) {
console.log(`num3 = ${para}`);
}
I'm not sure if what I am trying to do is impossible or not.
Consider this function:
function p(num) {
if (!num) num = 1;
return p.bind(null, num + 1);
}
if you call p(), inside the function num = 1, if you call p()(), num = 2 and so on. But, there is no way to actually return or obtain num from p because it always returns a bound copy of itself with the number trapped in its unexecutable closure.
Anyway, I'm curious (a) if there is a way to pull the argument out of the bound function, or (b) there is another way to count in this fashion.
I have two answers depending on what you want. If you simply want something "imperative" and "stateful":
function p() {
if (!p.num) p.num = 0;
p.num = 1 + p.num;
return p;
}
p();
p.num; // 1
p();
p.num; // 2
p()();
p.num; // 4
p()()();
p.num; // 7
Or if you want it to be "stateless":
function p() {
p.num = 0;
function gen_next(prev) {
function next() {
return gen_next(next);
}
next.num = prev.num + 1;
return next;
}
return gen_next(p);
}
p().num; // 1
p()().num; // 2
p()()().num; // 3
p()().num; // still 2
p().num; // still 1
As of right now my sum function looks like the code below. It works and returns the sum of the consecutive calls. But how can I make this work without the empty parenthesis at the end? Like so theSum(5)(4)(3) which returns 12.
function theSum(x) {
var total = x;
function rec(y) {
if (y === undefined) return total;
total += y;
return rec;
};
return rec;
}
console.log(theSum(5)(4)(3)()); // 12
Here is a suggestion utilizing a toString method:
function theSum(x) {
var total = x;
function rec(y) {
total += y;
return rec;
};
rec.toString = function() { return total; }
return rec;
}
alert(theSum(5)(4)(3));
console.log(parseInt(theSum(5)(4)(3)));
Note however that you need to convert the returned reference to a string in some way so that you see the result.
This is not possible. A function cannot return a function and an integer. You can make theSum(5, 4, 3) = 12 or theSum([5, 4, 3]) = 12.
Closures and JavaScript duck typing to the rescue:
function NumSumFun(initial){
function NumSumNext(num) {
initial+= num;
return NumSumNext;
}
NumSumNext.valueOf = function () { return initial; }
return NumSumNext;
}
var x = NumSumFun(10)(29); // ==> function 39
x + 1; // ==> 40
So whats happening. It returns a function but the function has a valueOf property that has access to the accumulated value so the function acts as a number when used as a number.
Let me propose an example that works, then follow up with what fails, highlighting the point to my question.
Here, we have 3 functions being called (1 named, 2 anonymous):
var add = function(a, b) {return a+b};
var multiply = function(a, b) {return a*b};
function myFunction(fxn) {
return function(x) {
return function(y) {
return fxn(x,y);
}
}
}
myFunction(add)(2)(3)
Understandably, this call fails:
myFunction(add)(2)(3)(4)
How would I detect how many functions are being called? In the 2nd call, I'm calling 4 functions (1 named, 3 anonymous).
How would I rewrite the myFunction function in a way that compensated for any given amount of calls? I know we can detect how many arguments a function was given, but is there a way to detect how many functions are being called? I hope I worded this correctly. Thanks.
To find out if a variable contains a reference to a function you can use below code:
if (typeof(v) === "function") alert("This is a function")
Based on above you can find out on how many nested functions there are
function myFunction() {
return function() {
return function() {
return 1 + 2;
}
}
}
var count = 0;
var v = myFunction();
while (typeof(v) === "function") {
count++;
v = v();
}
alert("Nr of nested functions: " + count)
Even if this has no practical use case I can think of, this is a possible solution:
var add = function(a, b) {
return a + b
};
var multiply = function(a, b) {
return a * b
};
var counter = 0;
var result = 0;
function myFunction(fxn) {
counter = 1;
result = 0;
return function first(x) {
++counter;
return function second(y) {
++counter;
x = result ? result : x;
result = fxn(x, y);
return second;
}
}
}
myFunction(add)(1)(2)(3)(4);
alert('Result is: ' + result + '; Parentheses count: ' + counter);
I know this question is already answered with limited capability but I want it with n number of time with n arguments?
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
problem is this works only when I add extra empty brackets ()
it doesn't work if do this add(1)(2)(3)
reference question
Try this:
function add(x) {
var fn = function(y) {
x = x + y;
return arguments.callee;
};
fn.toString = function(){ return x; };
return fn;
}
The following code works exactly like you asked:
function add(a)
{
var c=a,b=function(d){c+=d;return arguments.callee;};
b.toString=function(){return c;}return b;
}
Do note that some operations will detect the result given as a function, but any functions that require a string or integer will see the proper value.
Try sending your numbers as an array and changing your function code to reflect these changes.
Note: Code untested.
function add(x) {
var result = 0;
for (i = 0; i < x.length;i++){
result+=x[i];
}
return result;
}
add(new Array(1,2,3));