Since the assignment operator can essentially assign variables to values/objects why cant you assign a variable to a function.
For example: When I assign var b = 5; b turns into 5, same for Objects when I create an instance. var b = c;
However when I assign var b = func(); it gives me the result or the return. Why does it do this and how do you make a duplicate function without the use of a closure or factory?
The () characters are the syntax that means "call the function".
Remove them and you'll get the reference to the function object instead of calling it and getting the return value.
function func () {
alert(1);
}
var b = func;
b();
setTimeout(func, 2000);
Related
If I wanted to first declare a function, and then at some point I want to reference the function and not its return value to a variable, how would I do that?
var best = bestPresidentEver;
function bestPresidentEver(a,b){
//for some reason always returns Trump.
}
and then call best(a,b) instead of bestPresidentEver(a,b)
I am wondering how to do that opposed to assigning the function to the var upon declaration.
var best =
function bestPresidentEver(a,b){
//for some reason always returns Trump.
}
Declare your variable like this
var bestPresidentEver= function (a,b){
//for some reason always returns Trump.
return "Trump"; //:D
}
Then call that function like this
//You have to declare a and b variables
var trumpHere = bestPresidentEver(a,b);
If your function is already declared, just assign it to the variable :
function bestPresidentEver (a,b){
//for some reason always returns Trump.
return "Trump"; //:D
}
var trumpHere = bestPresidentEver;
Then call it like this :
var trumpAgain = trumpHere(a, b);
If the variable exists and it's not a const you can simply reassign it's value to the function itself.
Ex
var foo = 'foo';
function bar(a) {
return 'example ' + a;
}
bar('code'); //=> "example code"
/* Further down, reassign the `foo` variable */
foo = bar;
foo('code, again'); //=> "example code, again"
I am using SignalR, and I need to point it to a function, and I also want to call that function in other areas of the application.
If the library expects a function parameter, you can simply pass that function like so.
function first(next /* expects a function parameter */) {
return next('hello');
}
function second(prefix) {
return prefix+ ' world!';
}
first(second); //=> "hello world!"
It the code below I am not certain as to which way is better to write the code. The NewVar is a variable which I think can become which ever value is returned from the functions that are inside of the quotes. Is there a better way of writting this.
var NewVar = {
myVar: function() {
return AnotherValue;
},
isAny: function() {
return SomeValue;
}
};
Can you make the like this: Would the following work the same.
var NewVar;
function myFunc() {
//code here
}
function myFunc2() {
//code here
}
NewVar = myFunc();
or
NewVar = myFunc2();
The NewVar is a variable which I think can become which ever value is returned from the functions
No. NewVar is a variable that gets assigned an object literal that contains these two functions as properties. You can invoke them as methods (without changing NewVar):
console.log(NewVar.isAny()); // SomeValue
console.log(NewVar.myVar()); // AnotherValue
Your second snippet is totally different from that.
Not sure if I understand your question.
In your first snippet NewVar is a object which contains two methods (myVar and isAny) so I can do something like:
var foo = NewVar.myVar();
In the second snippet you are declaring two functions and then you assign to NewVar the return value of one of these functions.
Nope, these two examples are different. In the first example, you can call myVar and isAny as a member of NewVar:
NewVar.myVar(); // returns AnotherValue
NewVar.isAny(); // returns SomeValue
But in the second example, you assign the return value of the functions to the variable NewVar. For example, look at this example:
var myObject = {
addUp: function(a, b) {
return a + b;
}
};
myObject.addUp(1, 2); // returns 3
var myVar = myObject.addUp(1, 2); // myVar holds 3, because myObject.addUp(1,2) returns 3
I am trying to change the definition of a function:
var a = function(){alert('a');};
var b = a;
b = function(){alert('b');};
This results in the variable a keeping it's original assignment i.e. the function producing alert('a').
Is there any way of passing around a reference to a javascript function so that I can alter it later?
Would you expect the value of a to change after the following snippet? Snippet in question:
var a = 10;
var b = a;
var b = 20;
No, right? So why would you expect reassigning b to also affect a?
After line 1, you have a pointing to a function instance:
After line 2, you have a new variable b, also pointing to the same function instance. So now you have two variables, both pointing to the same instance:
After line 3, you have reassigned b to something else (a new function), but a is still pointing to the original function:
You can do what you want by doing something like this:
var func = function() { alert("a"); };
var a = function() { func(); };
var b = a;
func = function() { alert("b"); };
Now calling a() or b() will alert the string b.
Is there any way of passing around a reference to a javascript function so that I can alter it later?
There is no way to do this. Javascript does not have "pointers". It has reference values, and as such, a is a reference to the value of a, not to the memory location of a.
So, for this set of instructions
var a = function(){alert('a');};
var b = a;
b = function(){alert('b');};
this is the progression
//a is stored at some memory location
var a;
//b is stored at some memory location
var b;
//the memory location where a is stored has its value updated
a = function(){alert('a');};
//the memory location where b is stored has its value updated
//from the value stored at a's memory location
b = a;
//the memory location where b is stored has its value updated
b = function(){alert('b');};
You could produce the result you're looking for like this:
var fn = function() { alert('a'); };
var a = function() { fn(); };
var b = a;
fn = function(){ alert('b'); };
This code would produce the desired effect you're looking for because they'll both call fn() and you're changing the common underlying reference.
This question already has answers here:
dynamically call local function in javascript
(5 answers)
Closed 8 years ago.
I'm having a difficulty calling a function inside of another function when its name is in a variable:
var obj = {}
obj.f = function() {
var inner = {
a: function() {
function b() {
alert('got it!');
}
b(); // WORKS AS EXPECTED
x = 'b';
[x](); // DOESN'T WORK, NEITHER this[x]() window[x](), etc.
}
}
inner.a();
}
obj.f();
I tried prefixing [x]() with different scope paths but so far w/o success. Searching existing answers did not turn up anything. It works with this[x]() if b() is placed directly inside object inner. I would like to keep b() as a function inside function a() because of variable scope in function a(), otherwise I would need to pass many parameters to b().
////
Re duplicate question: Quentin provided a more elegant answer in this thread imo.
There is no sensible way of accessing an arbitrary variable using a string matching the name of the variable. (For a very poor way to do so, see eval).
[x](); // DOESN'T WORK
You're trying to call an array as a function
NEITHER this[x]()
The function isn't a property of the inner object.
window[x](), etc.
Since it isn't a global, it isn't a property of the window object either.
If you need to call a function based on the value of a string variable, then organise your functions in an object and access them from that.
function b() {
alert('got it!');
}
var myFunctions = {
b: b
};
x = 'b';
myFunctions[x]();
Try this. Currently you are assigning string to variable x, instead of a function variable.
x = b;
x();
The problem is with your assignment
use x = b instead of x = 'b' to assign the function object as the latter just assigns the string into x.
Once you fix your assignment you can invoke the function as
x();
a.x();
a[x]();
etc.
You should make array for the function and then access using name in your variable as follow:
var obj = {}
obj.f = function() {
var inner = {
a: function() {
// set up the possible functions:
var myFuncs = {
b: function b() {alert('got it!');}
};
//b(); // WORKS AS EXPECTED --> commented this code
x = 'b';
myFuncs[x]();
}
}
inner.a();
}
The function declaration b will be captured in the closure of the anonymous function expression assigned as a.
When var is used in a closure, there is no (available in JavaScript) Object which gets assigned a property similar to what happens with window in the Global Scope.
Writing a function declaration effectively vars the name of the function.
If you really want to access a variable (i.e. b) by String, you will either need to create an Object which holds b similar to what you've done for a, or (and possibly dangerously) rely on an eval to convert "b" to b.
If you can't create the whole Object ahead-of-time, you can use this format
/* in (higher?) scope */
var fnRef = {};
// now when you
function b() {/* define as desired */}
// also keep a ref.
fnRef['b'] = b;
// fnRef['b']() will work **after this line**
let's say your code is like this:
//instead of x = 'b'
x = function(){}
then your solution could be like this:
var obj = {}
obj.f = function() {
var inner = {
a: function() {
function b() {
alert('got it!');
}
b(); // WORKS AS EXPECTED
//you can define it as a variable
var x = function(){};
//and call it like this
x();
//or define it like this
this[x] = function(){};
//and call it like this
this[x]();
//but you are creating an array [x] which is not a function
//and you are trying to call an array????
[x](); // DOESN'T WORK, NEITHER this[x]() window[x](), etc.
}
}
inner.a();
}
obj.f();
I know that you can write following
var obj = {
test: 'something'
}
But in this code, the inner function does not refer to a variable, but to a function.
Is there any other way to write / call the inner function?
function outer(){
var a = "Outerfunction";
console.log(a)
innerFct: function InnerFct() {
var c = "Inner";
console.log(c)
} innerFct();
}
window.outer();
There are a couple of different things going on here.
In this code:
var obj = {
test: 'something'
}
you are using "literal object notation" to create -- well, an object with one property test and that property has a value of something
In your second case, you are creating a code block (yes, it is fun that both objects and code blocks use the same syntax {...} to define them.
Inside of a code block, the innerFct: becomes a label. Labels are used with some control flow statements to jump around. Forget about them, you really are better off not using them.
function outer(){
var a = "Outerfunction";
console.log(a)
function innerFct() {
var c = "Inner";
console.log(c)
}
innerFct();
}
outer();
or even
function outer(){
var a = "Outerfunction";
console.log(a)
var innerFct = function () {
var c = "Inner";
console.log(c)
}
innerFct();
}
outer();
You are confusing functions with objects.
When using an object, the colon is used to show key-value pairs.
var object = {
innerFct: function(){
console.log('rawr');
},
someVariable: 7
}
object.innerFct(); //logs rawr
object.someVariable = 4; //just changed from 7 to 4
Using a colon how you have it in your example is incorrect syntax. Also when you are creating a function within an object like that, you don't name the function again because you are already assigning it to a name on the object.
Then you can edit the function anytime by doing something like this:
object.innerFct = function(){
//new code
}
Doing object.innerFct() will call the function.
Other answers have sufficiently covered the object syntax and calling the function in scope. As I mentioned in the comment, you can just do this:
function outer(){
(function () {
var c = "inner";
console.log(c)
})();
}
window.outer();
And it logs inner just fine.
Edit: Private/hidden variables like innerFct in the original code sample can be captured in closures as well.
outer = function() {
var innerFct = function () { console.log("inner"); }
// innerFct is captured in the closure of the following functions
// so it is defined within the scope of those functions, when they are called
// even though it isn't defined before or after they complete
window.wrapper = function() { innerFct(); }
return function() { innerFct(); }
}
outer();
// each of these next three lines logs "inner"
window.wrapper(); // assigned to global variable
outer()(); // calling the returned function
var innerFctBackFromTheDead = outer(); // saving the returned function
innerFctBackFromTheDead();
There is also the object constructor/prototype syntax.
function Outer() {
this.inner = function() {
this.c = "inner";
console.log(this.c);
}
}
var out = new Outer();
out.c; // undefined
out.inner(); // logs "inner"
out.c; // "inner"
More information on the new keyword and prototypes: http://pivotallabs.com/javascript-constructors-prototypes-and-the-new-keyword/