Javascript ~ Calling a function inside a Variable - javascript

I have a variable that is the functions name. I want to be able to call on that function from the variable.
var CircuitBox= document.getElementById("QLCS")
var CircuitNumber = CircuitBox.selectedIndex;
var circuit = CircuitBox.options[CircuitNumber].value;
// This Variable takes on the functions name that id like to call
circuit;
Cheers!

In JavaScript object properties can be accessed via there name as a string by using bracket notation, eg:
var propertyVal = myObj["propertyName"];
And since globally scoped members are actually properties of the Global object, you can get the properties from the window object (which is a reference to the Global object). So, if your drop down list contains values that map to function names in the global scope, you can call that function like this:
window[circuit]();

I can think of two ways.
You can try window[circuit]() if it is a global function. The other option is to use eval, but eval is evil. So to avoid the evilness of eval, a better way might be to maintain a map of handlers:
var handlers = {
someValue: function() {
...
},
otherValue: function() {
...
}
};
In this map, you're associating someValue and otherValue with anonymous functions. So assuming that your select box contains the options someValue and otherValue, the appropriate function will be called based on what they select.
Then all you have to do is handlers[circuit]().

Related

How JavaScript assigns `name` attribute of function?

In JavaScript, when I define function like this
function aaa(){}
I can later access the name by name attribute:
aaa.name
which will return
"aaa"
However, when I define function via var, it technically should be anonymous function without name attribute:
var aaa=function(){}
But instead it assumes that aaa is function name and assigns it to name attribute:
aaa.name
will also return
"aaa"
How JavaScript decides what should be the name, especially considering the fact that assignments could use more complicated scenarios:
var aaa=bbb=function(){}
or
var aaa=arr[0]=function(){}
?
Javascript declares the name variable of the function by taking the left-hand side argument that is equal to the function, which is 'aaa' in all basic cases. In the first complex definition, you declared state above Javascript will take the variable ab and assign it to a function making the name 'ab'. In the final example, you provided it sets the function equal to a pointer in memory, which is not a defined variable, this sets the name property to an empty string because arr[0] is not a variable name but a pointer to memory.
Here is a JSFiddle displaying this.
Something like this:
Inferred function names
Variables and methods can infer the name of an anonymous function from
its syntactic position (new in ECMAScript 2015).
var f = function() {};
var object = {
someMethod: function() {}
};
console.log(f.name); // "f"
console.log(object.someMethod.name); // "someMethod"
Read the entire blog. It will clear all your queries.

call or access a local function by name

function f1 () {
console.log('f1')
}
var s = 'f1'
runLocalFunctionByName(s)
Is this possible at all to write runLocalFunctionByName() or just call f1 without typing f1 in the source code, but using a variable holding its name? I mean without modifying f1 into a method, that answer is obvious: just make myobj.f1 = function or declare it globally like f1= function(). I am talking about normal local functions declared with function keyword only, not as vars, global vars or some other object property.
Not without the use of eval, which is evil (when used for this purpose for sure!).
Global functions could be called as attributes of the window object, but if they are in a local/closure scope that's not possible.
If you need to call functions by name, the only proper solution is storing them as attributes on an object, and then using obj[s]() for calling them.
One way of doing this is by using the instantiating a Function object.
var runLocalFunctionByName = function(fName) {
return (new Function('','return '+fName+'();'))();
};
Calling runLocalFunctionByName with a name of a function will now return the output of the named function.
EDIT
In case of local functions, the scope has to be mentioned, so we can modify the code, such that:
var runLocalFunctionByName = function(fName, scope) {
return (new Function('','return '+(scope?scope:'this')+'.'+fName+'();'))();
};
You can't access a local function outside its scope until unless you assign it to a variable having an accessible scope. MDN: A function defined by a function expression inherits the current scope. That is, the function forms a closure. On the other hand, a function defined by a Function constructor does not inherit any scope other than the global scope (which all functions inherit)

Can I use function as an object inside the same function

I write the code as follows,
function Myfunction(){
Myfunction.myvar = "somevar";
}
After I execute the function, I can able to access Myfunction.myvar
How is it working? And If I do so, What is the problem hidden in this?
If any problem, please explain context of that.
Since the function does not execute until you call it, Myfunction.myvar is not evaluated immediately.
Once you call it, the function definition has been installed as Myfunction, so that it can be resolved when you do call it.
Something like the following would not work:
var x = {
foo: 1,
bar: x.foo } // x does not exist yet.
How is it working?
When you declare a function in some execution context, a binding is added to the variable environment of that context. When you reference an identifier, the current variable environment is checked to see if a binding exists for that identifier.
If no binding exists, the outer variable environment is checked, and so on, back up to the global scope.
So:
// OUTER SCOPE
// Binding exists for 'example'
function example() {
// INNER SCOPE
// No binding for 'example'
// References 'example' in outer scope
example.x = 1;
}
What is the problem hidden in this?
There are none (in general... although whether it's the right solution for you depends on what you're trying to do).
You are effectively creating a "static" property of the function. As JavaScript functions are first-class you can set properties on them as you would with any other object.
Note that the behaviour is different if you have a named function expression, rather than a function declaration:
var x = function example () {
// Identifier 'example' is only in scope in here
};
One problem you might get because of scoping, as a more complicate example shows:
function Other() {
console.log("a) Other.Myvalue",Other.Myvalue);
Other.Myvalue=typeof Other.Myvalue==='undefined' ? 0 : Other.Myvalue+1;
console.log("b) Other.Myvalue",Other.Myvalue);
}
Other();
Other();
this would lead to
a) Other.Myvalue undefined
b) Other.Myvalue 0
a) Other.Myvalue 0
b) Other.Myvalue 1
so you realy bind your variable Myvar to the function object itself which is a singleton and exists just once (and is created by the function definition itself in the current context which may be the global context), not to an instance of that object. But if you just use static values and don't need any logic, it's like the literal form, and I wouldn't expect any problems, other that the literal form is more convenient:
var Other = {
Myvalue: "somevalue"
};
In javascript every function is an object. So you can add any custom fields to it.
function A() {}
A.somevar = 'this is custom field';
A.prototype.somevar2 = 'this is field in A proto';
So when you will create new object with A contructor it will take properties from prototype.
var b = new A();
alert(b.somevar2);

Is it preferable to use "this" or "that" (where var that = this)?

I'm fairly new to JavaScript and I'm cleaning up some JavaScript code I downloaded. One of the inconsistencies in this code is mixed usage of both this and the local variable that that references it.
An example code snippet (private method within a jQuery UI widget):
_populateLists: function(options) {
//do stuff with this
var that = this;
options.each(function(index) {
//use both this AND that, they are different in this scope
});
//here this and that are the same thing
//I want to be consistent, is one preferable over the other?
},
In many places throughout the code, where the scope is such that this === that, there is mixed usage, even within the same line of code.
For the sake of readability and maintainability, is it preferable to use this or that?
Note: I realize a lot of these types of things depend on developer preference. But before I decide to rewrite the code to use one over the other, I'd like to understand any reasoning if/why one would be preferred over the other.
EDIT: In this script, I think the only reason this is being assigned to a local variable is so that it can be referred to from within the inner closure.
The reason that the value of this is commonly assigned to a local variable is so that you can close over that value and use it inside a nested function.
this is a special variable and somewhat different from normal local variables in that it is automatically set to the object upon which a function was called (if any); otherwise, the global object. However, this intrinsic value of this is somewhat muddied by jQuery's liberal use of call and apply, which allow the caller to specify the value of this.
In a nested function, this does not inherit the value of its parent's this in the same way it would inherit a parent's local variables through the scope chain.
Because of this, we have to stash the value of this in a local variable if we need it inside a nested function, such as the each callback in your example.
var a = { fn: function() {
// here, `this` is the object `a`
var x = this;
function b() {
// here, `this` is `window` because `b` is invoked with no context
// ...but we still have access to `x`, whose value would be `a`
}
b();
}};
a.fn(); // by invoking `fn` as a property of `a`, we implicitly set `fn`'s
// `this` to `a`.
// Compare to:
var f = a.fn;
f(); // we now invoke `fn` with no context, so its `this` will be `window`.
a.fn.call(window); // or by specifying context explicitly
Of course, when you're still in the parent scope, this will still equal that (or self or whatever). At first glance, it may seem like there's no difference between the two, but there is one important performance impact:
Minification. If you assign this to a local variable, all references to that variable can be reduced to one character. References to this cannot. Compare this minified output:
function a() {this.w=1;this.x=2;this.y=3;this.z=4;}
function b() {var t=this;t.w=1;t.x=2;t.y=3;t.z=4;}
With 4 references to this, you save bytes by using a variable. If you have to capture this for an inner function anyway, using the local variable instead of this in the outer function gets you savings even with a single reference.
There isn't any reason, other than the standard subjective rationales of consistency and meaningful variable names.
If you go to the trouble of assigning this to a local variable, it's probably a good idea to use it, especially if you've given the local variable a useful name:
$('body').on('click', '.something', function() {
var clicked = this;
// now "clicked" is the element clicked on
});
for a jQuery example, but it's the same issue regardless of library or in raw JavaScript. Personally I think "that" is a pretty weak variable name in almost all cases.
If the purpose of assigning this to a local variable is to achieve semantics, then it would make sense to use a semantic variable name and then use the variable rather than this.
But since the purpose of assigning this to a local variable in this scenario is to cache it for use in an inner function, I think it's more readable/semantic to continue to use this in the outer scope.
While that is not normally a very good variable name, I think the meaning remains clear in this scenario. In my mind, in the inner scope, that is to this as parent is to self.
And since this is a jQuery UI widget, I looked at the source of some of the standard widgets that 'ship' with jQuery UI. It seems to be a standard convention to use this throughout except when needing to refer to the this of the outer scope. In the latter case, this is cached in a variable named that. Even when the local variable exists, it's only used in the inner scope.
Example for clarity:
_populateLists: function(options) {
var that = this; //we'll need `this` within a closure later
//do some stuff with `this`
options.each(function(index) {
//do stuff with `this` AND `that`
//`that` is the `this` of the outer scope
});
//do some more stuff with `this`
},
If consistency is the goal, then it makes sense to follow the same convention used by standard jQuery UI widgets.
When assigning a variable to $(this) when using jQuery, it is preferable to use $this as it refers to a jQuery object ( $ ). It is commonly used when $(this) no longer refers to the parent object when in the scope of another function.
The variable name however does not matter and simply refers to the object assigned. We could use $this, $that, $obj, that, obj, button etc. as our variable name, however this in javascript is a reserved word referring to the object in the current scope so we cannot use this as the variable name. You cannot assign any type of value to this or $(this).
Example...
this = 'something'; // or
$(this) = 'something';
Both of the above statements will throw an exception.
An example using $this = $(this); is shown below
To change the html of a button with the id of "someButton" after a successful jQuery post...
$('#someButton').click(function() {
var data = $('form').serializeArray();
// some validation or something
$this = $(this);
// note the lack of the var command to
// globalize $this within the click function
$.post('somePage',data,function(html) {
$this.html(html);
// identical to $('#someButton').html(html);
});
});

Pass a function reference that has a variable as its name

I have the following javascript method:
function 123_test_function(){
}
The function is generated by java and sent to the client. The 123 is the id of the component so it could change. i.e I can have another function called 111_test_function()
I want to pass this function as a reference.
So I need to create the reference
var 123_test_function = function 123_test_function(){
}
In another js file inside an object I have a function that needs to use the 123_test_function reference like so:
useFunction(123_test_function);
The problem I'm having is which the 123 part of the function.
In this object I have a variable(uniqueID) which has the number at the beginning of the function.
I need the function call to be something like:
useFunction(uniqueID+"_test_function");
This doesn't seem to pass a function instead it passes a string.
Am I doing something wrong?
For one, identifiers (such as function names) cannot begin with a digit.
To solve your problem, use an object, like this:
// 1. define an object to hold all your functions
var allFunctions = {};
// 2. store any function with a unique string as the ID
allFunctions['123_test_function'] = function () {
// whatever
};
// 3. call the function
allFunctions['123_test_function']();
allFunctions[uniqueID + '_test_function']();
Objects are associative arrays. They store key/values pairs, so they do exactly what you want here.
Note that functions don't need a name in JavaScript, so I did not use on in step 2.
If the function is defined as global one, it will be a member of global object (window in case of browsers). Hence you can just do window['id_'+uniqueID+'_test_function'] to access your function
useFunction(window['id_'+uniqueID+'_test_function'])
(Identifiers cannot begin with numbers in JavaScript so I added the 'id_' prefix. You can of course change it to your liking.)
function test_function(number){
if(number == 1)
{
return function() {}
}
if(number == 2)
{
return function() {}
}
}
call the function like this
var func = test_function(1)
func();
As a couple of people have correctly pointed out, a function (or indeed variable) name cannot begin with a numeric. Also this syntax is wrong:
var 123_test_function = function 123_test_function(){
}
The correct syntax would be:
var 123_test_function = function() {
};
...although it should also be noted that the effect of this is exactly the same as a "traditional"
function 123_test_function() {
}
...declaration, in the context of the window object - since window is effectively the global scope of a JS environment in a browser, it doesn't matter how you define the functions, they will always be accessible from anywhere. Understanding exactly what each method of declaring a function means in Javascript is important - luckily, Douglas Crockford to the rescue once again...
People have suggested various methods for calling your named functions from the context of a string, which is basically attempting to use "variable variable" syntax, a subject that has been discussed on SO and elsewhere at length. The eval() approach should be avoided wherever possible - if you find yourself needing an eval() chances are you went wrong somewhere a while back. #Tomalak has the right idea with a collection of functions held in an object, but this still needs the slightly messy string approach to reference things that are actually being accessed by a numeric ID. The collection approach has the advantage of not cluttering up the window object with what are likely to be single/zero use members.
But the way I see it, all you actually need here is an indexed array of functions, where all you need is the numeric index in order to access them. I suggest you create your functions like this:
// Do this once at the top of your JS
var test_functions = [];
// Now, for each function you define:
test_functions[123] = function() {
// Do stuff here
};
// And when you need to call the functions:
var funcId = 123;
test_functions[funcId]();

Categories