Assign a function with custom parameters without calling the funcion - javascript

I've a function A which accepts at run-time another function B as parameter and calls it. The problem is the function B needs some parameters, but I don't know how to pass the function B, with parameters, to the the function A.
Example:
function callerFunction(c)
{
alert("The caller is calling the function!");
c(c.arguments);
};
var a = "hello";
function thisOne(d)
{
d = "I changed my way";
alert(d);
};
callerFunction( /* I NEED TO PASS THE 'thisOne' with the parameter/variable 'a' here, and then call it inside 'callerFunction' */);

Just pass a closure:
callerFunction(function() { thisOne(a); });
And call it as c(), not c(c.arguments).
Note that this anonymous function will reference the a variable, not the value a had at that moment. So if callerFunction() was to store this function object and call it later, if you changed the value in a between passing the anonymous function and the time it is called, the value of a from the perspective of the anonymous function would have changed:
var a = 1;
var fn = function() { console.log(a); };
fn(); // Logs 1
a = 2;
fn(); // Logs 2

Related

Javascript module pattern and function invocation

Hello I have started to learn some javascript and I can't wrap my head around this in "normal" functions. I don't understand why the following two functions output different results. f2 outputs 5, while f1 outputs 1. Why is that?
var f1 = function(){
var x= 1;
var add = function(){
x=5;
};
var result = function(){
console.log(x);
};
return {
add: add,
result: result
};
};
f1().add();
f1().result();
var f2= (function(){
var x= 1;
var add = function(){
x=5;
};
var result = function(){
console.log(x);
};
return {
add: add,
result: result
};
})();
f2.add();
f2.result();
The first example shows two invocations of f1().
The first invocation of f1() creates a new variable scope with x set to 1, and returns the object with the methods. The .add() then sets that x to 5.
The second invocation of f1() creates another new variable scope with x again set to 1, and returns the object with the methods. The .result() then returns that x which is still 1.
The second example only invokes f2() once, so there's no new variable scope with x and new methods being created.
So basically f1's two invocations initializes x with each call, and returns two different objects with methods that closer over the two different x variables.
The f2 is invoked once so there's one x variable shared by the one object with methods returned. Therefore the .add() call and the .result() call are using the same x variable.
Let me outline what happens in your code:
// Declares a function named f1.
var f1 = function () {
// Searches each scope (the scope of f1, the scope containing f1, etc.) for
// a variable named x. If found, it will reassign it to 1. If the search reaches
// the global scope and no variable is found it will declare and initialize
// a global variable.
x = 1;
// Declares a local variable named add to a function that reassigns the value of x.
var add = function () {
x = 5;
};
// Declares a local variable named result to a function that logs the value of x.
var result = function () {
console.log(x);
};
// Returns an object containing each function.
return {
add: add,
result: result
};
};
// Calls f1 and the returned add function.
f1().add();
// Calls f1 again (which reassigns x) and calls the returned result function.
f1().result();
// Creates a variable named f2 and assigns to the result of applying an anonymous
// function. f2 now references the returned object.
var f2 = (function () {
// Reassigns x, does not create a new variable.
x = 1;
var add = function () {
x = 5;
};
var result = function () {
console.log(x);
};
return {
add: add,
result: result
};
})();
// The difference now is that the function that contains add and result is only
// called once, during the initialization of f2. Had you written var g = f1();
// g.add(); g.result(); you would have gotten the exact same results.
f2.add();
f2.result();

What is difference between these two functions?

I have tried folllowing two ways of referring a function:
First
let a = function() {
somefunction();
}
Second
let a = somefunction;
Where somefunction is the following in both cases:
function somefunction() {
alert("hello");
}
Is there any difference between these two ways?
Yes, there is a difference between your two examples.
In the first case, you are defining a new anonymous (unnamed) function which calls somefunction. You are then assigning your new function definition to the variable a. a holds a reference to your new function.
In the second case, you are simply assigning your original function of somefunction to the variable a. The variable a then holds a reference to somefunction. You are not creating a new function as you are in the first case.
I think this example may make the difference clear. arguments is an array like object that contains each of the arguments passed to a function.
Try running each of these lines on your favorite browser console.
var somefunction = function() { console.log(arguments); };
Your first example demonstrates defining a named function a that closes around the named function somefunction.
var a = function() { somefunction(); };
Your second example makes a reference, b, directly to somefunction. This makes invoking b the same as invoking somefunction.
var b = somefunction;
Now if you call each of these a and b with some arguments you will see the difference.
=> a('a', 1);
[]
=> b('a', 1);
['a', 1]
In the first case the arguments object is empty. That's because the arguments that were passed to a were not forwarded onto somefunction.
In the second case the arguments are available to somefunction, because some function is being called directly.
Here is how you could redefine a so that it were functionally equivalent using apply
var a = function() { somefunction.apply(this, arguments); }
Running this at your console prints the argument array.
=> a('a', 1);
['a', 1]
var a = function(){
somefunction();
}
Is an Anonymous Function attributed to a variable.
somefunction :function() {
alert("hello");
}
Is an declaration of a function throungh the Object Literal notation.
The diference are shown when you are creating an object. The anonymous function are not acessible as a "public" method, instead in the Object Literal notation, that are acessible from outside.
As Douglas Crockford said, in JS the Good Parts, the first declaration are just a function and the second one could be a method.
In the first case, you are creating a function which calls someFunction(), then you assign that function to a, so now calling a() calls an anonymous function which in turn calls someFunction().
In the second case, a and someFunction become the exact same thing, calling a() is the same as calling someFunction().
The way you're setting var a by accessing the function is clearly out of scope.
So I suspect you have a typo : instead of = :
var somefunction = function() {
alert("hello");
};
somefunction(); // hello
...Now that your first and second makes sense with the code above:
Anonymous Function stored in variable:
var a = function(){
alert('Hey');
somefunction();
};
a(); // Hey // hello
Variable as Function Reference
var a = somefunction;
a(); // hello
In the other case than:
var objLiteral = {
somefunction : function() {
alert("hello");
}
};
var a = objLiteral.somefunction;
a(); // hello

Passing function by variables

I've this situation:
<script>
var cb;
function doSomething(c) {
cb = c();
}
cb();
</script>
But it doesn't work. I want to set a variable as function, to make a callback called by other functions.. Some ideas?
c() executes the function and returns a value, you need to pass a reference to it:
cb = c
Also, you should call the function doSomething(func) to make the assignment.
doSomething(function(){ alert('hello'); });
cb(); // "Hello"
But if what you want is a callback then you don't need a global variable:
function doSomething(callback) {
// do something
if (callback) callback();
}
When you run the function with another function as parameter the callback will run.
You need to assign cb first with your function:
<script>
var cb;
function doSomething(c) {
cb = c;
}
var myFunc = function(){
window.alert("test");
}
doSomething(myFunc);
cb();
</script>
And if you do cb=c(); you will execute function c instantly and return the value to cb if you want the variable cb as the result of c, do like this. otherwise, assign without running it.
You have 3 options to set a variable to a functiion
var fn = functionname;
var fn = function(param){}; this will be an anonymous function
var fn = function FunctionName(param){}; this will be a named function, comes in handy when debugging, since it will present you with a function name (console.log(c);
You cann call it like var returnVal = fn(); or pass it to a function var returnVal = myFunc(fn); where myFunc calls the param, let it be inFn it like inFn();
What might be interesting to note:
Since such a function is related to the global context, you can bind an object to it alter its scope. That gives you the possibility of thisreferencing the bound object. (Be aware, bind is not supported by all browsers as it is defined ECMAScript 5, but there are quite some polyfills out there.)
fn.bind(object);
Or call it in another context with fn.call(object, param1, param2) or fn.apply(object, [param1, param2]). Nice write up on this Link to odetocode.com/blog.

passing an anonymous function to another function in Javascript

I understand you can pass a function as an argument to another function like so
var fn = function(){alert('Hello')}
function outer(a,fn){
fn();
}
How can you pass an anonymous function to another function and have it invoked within the function after taking a parameter from the outer function?
function outer(function(x){alert(x);})
{
var xVar = "foo";
//..would liked to pass xVar to the anaonymous function
//passed as a param to the function so that "foo" is displayed as message...
}
Please note changing the signature of outer would be the last choice.
You're confusing function invocation (calling a function) with function declaration (defining a function). Here's how do what you ask:
// declare the outer function
function outer(func)
{
var xVar = 'foo';
func(xVar)
}
// now invoke it
outer(function (x)
{
alert(x);
});

how to use function(1)(2) in javascript? and how does it work?

I understand calling function(1) but not function(1)(2), how does it work?
also possible for function(1)(2)(3)(4) too?
In this case you are supposing that function(1) returns a function, than you are calling this new, anonymous function with an argument of 2.
See this example:
function sum(a) {
return function(b) {
return a+b;
}
}
// Usage:
window.alert(sum(5)(3)); // shows 8
var add2 = sum(2);
window.alert(add2(5)); // shows 7
window.alert(typeof(add2)); // shows 'function'
Here we create a function sum that takes one argument. Inside the function sum, we create an anonymous function that takes another argument. This anonymous function is returned as the result of executing sum.
Note that this anonymous function is a great example of what we call closure. A closure is a function that keeps the context in which it was created. In this case, it will keep the value of the variable a inside it, as did the example function add2. If we create many closures, they are independent as you can see:
var add3 = sum(3);
var add4 = sum(4);
window.alert(add3(3)); // shows 6
window.alert(add4(3)); // shows 7
Furthermore, they won't get "confused" if you have similarly named local variables:
var a = "Hello, world";
function multiply(a) {
return function(b) {
return a * b;
}
}
window.alert(multiply(6)(7)); // shows 42
var twoTimes = multiply(2);
window.alert(typeof(twoTimes));
window.alert(twoTimes(5));
So, after a call to sum(2) or multiply(2) the result is not a number, nor a string, but is a function. This is a characteristic of functional languages -- languages in which functions can be passed as parameters and returned as results of other functions.
You have a function that returns a function:
function f(n) {
return function(x) {
return n + x;
};
}
When you call f(1) you get a reference to a function back. You can either store the reference in a variable and call it:
var fx = f(1);
var result = fx(2);
Or you can call it directly:
var result = f(1)(2);
To get a function that returns a function that returns a function that returns a function, you just have to repeat the process:
function f(n) {
return function(x) {
return function(y) {
return function(z) {
return n + x + y + z;
}
}
};
}
If your function returns a function, you can call that too.
x = f(1)(2)
is equivalent to:
f2 = f(1)
x = f2(2)
The parenthesis indicate invocation of a function (you "call" it). If you have
<anything>()
It means that the value of anything is a callable value. Imagine the following function:
function add(n1) {
return function add_second(n2) {
return n1+n2
}
}
You can then invoke it as add(1)(2) which would equal 3. You can naturally extend this as much as you want.

Categories