I'm trying to call a js function within another one, but use the argument to specify the function. ie depending on the argument passed, it will call a different function
function toggle(n){
if (sessionStorage['toggle'+n]== 0){
check+n();
}
else
}
So, for example, if the argument 'Balloons' was passed as n, then it will call the function checkBalloons(). "check+n();" is not currently working here. Sorry for my lack of simple js syntax!
If the function is defined in the global scope (browser) you can do:
window["check"+n]();
or some tenants like Node.js you would access it from global object.
global["check"+n]();
if it is a part of some other object then you would do the same.
obj["check"+n]();
Functions and properties defined on an object can be accessed using [] convention as well. i.e obj["propFuncName"] will give you reference to it, so in case of methods you add () to invoke it.
If the function is global, you would do this:
window["check" + n]();
or, you could put your function in an object like so:
myNamespace = {};
myNamespace.checkSomething = function(){ /* ... */ }
// call it like this:
myNamespace["check" + n]();
The answers thus far are correct, but lack explanation.
In JavaScript, you cannot call a function by name when that name is a string. What you can do is retrieve a value from an object by name, and if that value happens to be a function, you can then call it. For example:
var myObject = {};
myObject.myFunction = function() { alert('test!'); };
// Get the property on `myObject` called `myFunction`
var theFunctionLookup = myObject['myFunction'];
// Since that property was a function, you can call it!
theFunctionLookup();
In the browser, functions that are defined in the global scope are attached to the window object. For example, this works:
function myFunction() { alert('test'); }
var theFunctionLookup = window['myFunction'];
theFunctionLookup();
You can shorten the last two lines into one:
function myFunction() { alert('test'); }
// Look up and call the function in one line.
window['myFunction']();
For the same reasons, you can use a dynamically-calculated string to look up functions.
function checkBalloon() {
alert('checking balloon');
}
function toggle(n){
if (sessionStorage['toggle'+n]== 0){
window['check' + n]();
check+n();
}
}
toggle('Balloon');
if you do this way:
if (sessionStorage['toggle'+n]== 0){
window["check" + n]();
}
will work
Related
So I was getting the following error:
TypeError: parentRef.parentFunction() is not a function
in my callee.
My callee looked sort of like this
function callee(parentRef){
function subRoutine(){
//stuff
parentRef.parentFunction(params);
}
}
And the caller looked like this:
function caller(){
refToCallee = new callee(this);
refToCallee.subRoutine();
parentFunction(prms){
//other stuff
}
}
Then I realized that I had seen code that changed the caller to have the following line when defining parentFunction
this.parentFunction = function(){ etc.}
What is the thiskeyword doing here. Is it a namespacing thing? More specifically why does my first definition without using the this.funcName syntax not work?
When you define a function like parentFunction inside another function like caller, there are 3 ways of doing it.
function parentFunction() { ... }
var parentFunction = function() { ... };
this.parentFunction = function() { ... };
The first declares a function inside the scope of caller. It is only usable inside caller.
The second declares a local variable that happens to be a function, it is also only callable inside caller.
The third declares a property on the caller object that happens to be a function. Anyone with a reference to a caller object (like in your example) can call it. This is why the this.parentFunction is needed for callee to be able to use it.
What you have in your original example,
parentFunction(prms) { ... }
is not proper javascript. It does not declare a variable or a function, nor does it execute any code.
It appears you want a callback like this:
function callee(callback){
//stuff
callback(params);
}
function caller(){
callee(callback);
function callback(prms){
//other stuff
}
}
I have a function localised to the main function and i want to use this to call it but it doesn't seem to work.
My code has:
function option(room,slot){
var div_id = document.getElementById(room);
var opacity = window.getComputedStyle(div_id).opacity
transition_opacity(div_id,opacity,0,function(){this.load});
function load(){
console.log('test'); //does not happen
}
}
Have i misunderstood the use of this or is the scope lost when i use function(){} to call load?
From your code it is not obvious, what object this could refer to. It depends on how option is called. However, if you define the load function inside of the option function anyway, it is best to just reference it directly. You will have to move the declaration of test above the transition_opacity call though:
function option(room,slot){
var div_id = document.getElementById(room);
var opacity = window.getComputedStyle(div_id).opacity;
function load() {
console.log('test');
}
transition_opacity(div_id,opacity,0,load);
}
As you can see, I just reference load directly. You could make another function which calls the load function inside (i.e. function() { load(); } – note the parentheses which calls the function) but that would give you no benefit but would just add another unneeded function to the stack. So just refer to the actual function itself.
For more information on the this keyword, check out this question. Spoiler: It’s more complicated than you would expect.
The scope of this is lost in this instance, probably pointing to the document. You can capture this to a variable in the outer scope to make this work as intended.
var context = this;
transition_opacity(div_id,opacity,0,function(){context.load();})
The above will not work however. This is because load does not exist on the context of this. You would need to define the load function as such:
context.load = function(){
console.log('test');
}
Both.
First, your load function is not a member/property of any this, the way you have it coded. Your load function is simply a nested function that exists within your option function, as has been sort of implicitly noted in other responses.
In your option function, if you want 'load' to become a member of 'this', you'd need to say so, like this:
function option(){
this.load = function(){}; // now load is actually a property of whatever this is
}
Second, you and the other poster are correct that 'this' is no longer the same 'this' by the time your anonymous function is called.
Whenever you call a function, a brand new 'this' is created and exists within the scope of that function. If you just call a function like this:
transition_opacity(args);
.. then within transition_opacity, 'this' just refers to the window object, or maybe window.document. For 'this' to refer to anything other than window or window.document, you need to (in effect) do one of the following:
myObject.transition_opacity(args);
transition_opacity.call(myObject, arg1, arg2, ..);
transition_opacity.apply(myObject, argArray);
or
var myObject = new transition_opacity(args);
In each of those cases, within transition_opacity, 'this' refers to myObject (or, well, in the last case, it refers to a new object that is being created and assigned to myObject).
Here is a way to do what it looks like you're trying to do:
var MyNamespace = {
option: function(room,slot){
var div_id = document.getElementById(room);
var opacity = window.getComputedStyle(div_id).opacity;
var _this = this;
transition_opacity(div_id,opacity,0,function(){
// Careful! Inside here, 'this' is just window or window.document,
// unless transition_opacity sets it to something using call or apply,
// in which case that 'this' is probably not the 'this' you want.
// So carefully refer to the saved instance of 'this':
_this.load();
});
},
load: function(){
console.log('test'); // now it should happen
}
}
.
.
MyNamespace.option(room, slot); // inside option, 'this' is MyNamespace.
Here's another way to do it:
function MyClass(){};
MyClass.prototype = {
// all the same stuff that is in MyNamespace above..
};
.
.
var myObject = new MyClass();
myObject.option(room, slot);
Clear as mud?
Just use
transition_opacity(div_id,opacity,0,load);
You have defined a 'load' within another function as an 'Function Declaration', so now it is only accessible within 'option' function and in other functions defined in this one by name 'load'. You can't access it by using 'this.load' no matter what 'this' is. If you want to access 'load' function as 'this.load' you can try this example to understand how 'this' keywoard works
// Function Declaration
function f1(callback){
callback();
};
// Function Declaration
function f2(){
// Function Expression
this.load = function(){
console.log("test");
};
f1(this.load);
};
var obj = new f2(); // test, this == obj, so obj.load() now exists
obj.load(); //test, this == obj
f2(); //test, this == window, so window.load() now exists
load(); //test, window is the global scope
Ok hopefully this come across correctly. I am building a universal javascript function that will build a menu and then also build the functions that each menu item would call. To do this, I need to pass a list of the commands to be called for each option.
So for example:
var thecall = 'alert("hi, this works");';
function myfunction(thecall)
{
//In here I want to excute whatever commands is listed in variable thecall
.....
}
I'm sure doing it this way is completely stupid, but I don't know how else to do this.
Basically, I need my function to perform other functions on a variable basis.
Thanks!!
I made it a bit fancier to show you how you can use it.
var thecall = function(name){alert("hi " + name + ", this works");};
function myFunction(function_ref)
{
function_ref('Mark');
}
myFunction(thecall);
You can execute arbitrary strings of JavaScript using eval(), but that is not the best solution for you here (it's almost never the best solution).
Functions in JavaScript are themselves objects which means you can store multiple references to the same function in multiple variables, or pass function references as parameters, etc. So:
var thecall = function() {
alert("hi, this works");
};
function myfunction(someFunc) {
someFunc(); // call the function that was passed
}
myfunction(thecall); // pass reference to thecall
Note that when passing the reference to the thecall function there are no parentheses, i.e., you say thecall not thecall(): if you said myfunction(thecall()) that would immediately call thecall and pass whatever it returned to myfunction. Without the parentheses it passes a reference to thecall that can then be executed from within myfunction.
In your case where you are talking about a list of menu items where each item should call a particular function you can do something like this:
var menuItems = [];
function addMenuItem(menuText, menuFunction) {
menuItems.push({ "menuText" : menuText, "menuFunction" : menuFunction });
}
function test1() {
// do something
}
addMenuItem("Test 1", test1);
addMenuItem("Test 2", function() { alert("Menu 2"); });
// and to actually call the function associated with a menu item:
menuItems[1].menuFunction();
Notice the second menu item I'm adding has an anonymous function defined right at the point where it is passed as a parameter to addMenuItem().
(Obviously this is an oversimplified example, but I hope you can see how it would work for your real requirement.)
I think your looking for the eval function.
var code= 'alert("hi, this works");';
eval(code);
I defined a global Javascript function:
function resizeDashBoardGridTable(gridID){
var table = document.getElementById('treegrid_'+gridID);
.....
}
After this function was used a few times, I want to remove(or undefined) this function because the Procedure code should be called again. if somebody try to call this method we need do nothing.
I don't way change this function right now.
so re-defined this function may be one way:
function resizeDashBoardGridTable(gridID){
empty,do nothing
}
Thanks. any better way?
Because you're declaring it globally, it's attached to the window object, so you just need to redefine the window function with that name.
window.resizeDashBoardGridTable = function() {
return false;
}
Alternately you could redefine it to any other value or even to null if you wanted, but at least by keeping it a function, it can still be "called" with no detriment.
Here's a live example of redefining the function. (thanks TJ)
An additional reason for pointing out that I'm redefining it on the window object is, for instance, if you have another object that has that function as one if its members, you could define it on the member in the same way:
var myObject = {};
myObject.myFunction = function(passed){ doSomething(passed); }
///
/// many lines of code later after using myObject.myFunction(values)
///
/// or defined in some other function _on_ myObject
///
myObject.myFunction = function(passed){}
It works the same either way, whether it's on the window object or some other object.
how about using a var?
// define it
var myFunction = function(a,b,c){
console.log('Version one: ' + [a,b,c].join(','));
}
myFunction('foo','bar','foobar'); // output: Version one: foo,bar,foobar
// remove it
myFunction = null;
try { myFunction(); console.log('myFunction exists'); }
catch (e) { console.log('myFunction does not exist'); }
// re-define it
myFunction = function(d,e,f){
console.log('Version two: ' + [d,e,f].join(','));
}
myFunction('foo','bar','foobar'); // output: Version two: foo,bar,foobar
OUTPUT:
[10:43:24.437] Version one: foo,bar,foobar
[10:43:24.439] myFunction does not exist
[10:43:24.440] Version two: foo,bar,foobar
The simplest approach is to set the function (treat it as a variable) to null. This works even if you don't declare it as a var. Verified this on IE.
resizeDashBoardGridTable = null
If the functions needs to be called 1 time you use an anonymous self invoking function like this:
(function test(){
console.log('yay i'm anonymous');
})();
If you have to call the function multiple times you store it into a var and set it to null when you're done.
Note: You don't have to name an anonymous function like I named it test. You can also use it like this:
(function(){
console.log('test');
})();
The reason I do name my anonymous functions is for extra readability.
I want to write my own function in JavaScript which takes a callback method as a parameter and executes it after the completion, I don't know how to invoke a method in my method which is passed as an argument. Like Reflection.
example code
function myfunction(param1, callbackfunction)
{
//do processing here
//how to invoke callbackfunction at this point?
}
//this is the function call to myfunction
myfunction("hello", function(){
//call back method implementation here
});
You can just call it as a normal function:
function myfunction(param1, callbackfunction)
{
//do processing here
callbackfunction();
}
The only extra thing is to mention context. If you want to be able to use the this keyword within your callback, you'll have to assign it. This is frequently desirable behaviour. For instance:
function myfunction(param1, callbackfunction)
{
//do processing here
callbackfunction.call(param1);
}
In the callback, you can now access param1 as this. See Function.call.
I too came into same scenario where I have to call the function sent as parameter to another function.
I Tried
mainfunction('callThisFunction');
First Approach
function mainFuntion(functionName)
{
functionName();
}
But ends up in errors. So I tried
Second Approach
functionName.call().
Still no use. So I tried
Third Approach
this[functionName]();
which worked like a champ. So This is to just add one more way of calling. May be there may be problem with my First and Second approaches, but instead googling more and spending time I went for Third Approach.
function myfunction(param1, callbackfunction)
{
//do processing here
callbackfunction(); // or if you want scoped call, callbackfunction.call(scope)
}
object[functionName]();
object: refers to the name of the object.
functionName: is a variable whose value we will use to call a function.
by putting the variable used to refer to the function name inside the [] and the () outside the bracket we can dynamically call the object's function using the variable. Dot notation does not work because it thinks that 'functionName' is the actual name of the function and not the value that 'functionName' holds. This drove me crazy for a little bit, until I came across this site. I am glad stackoverflow.com exists <3
All the examples here seem to show how to declare it, but not how to use it. I think that's also why #Kiran had so many issues.
The trick is to declare the function which uses a callback:
function doThisFirst(someParameter, myCallbackFunction) {
// Do stuff first
alert('Doing stuff...');
// Now call the function passed in
myCallbackFunction(someParameter);
}
The someParameter bit can be omitted if not required.
You can then use the callback as follows:
doThisFirst(1, myOtherFunction1);
doThisFirst(2, myOtherFunction2);
function myOtherFunction1(inputParam) {
alert('myOtherFunction1: ' + inputParam);
}
function myOtherFunction2(inputParam) {
alert('myOtherFunction2: ' + inputParam);
}
Note how the callback function is passed in and declared without quotes or brackets.
If you use doThisFirst(1, 'myOtherFunction1'); it will fail.
If you use doThisFirst(1, myOtherFunction3()); (I know there's no parameter input in this case) then it will call myOtherFunction3 first so you get unintended side effects.
Another way is to declare your function as anonymous function and save it in a variable:
var aFunction = function () {
};
After that you can pass aFunction as argument myfunction and call it normally.
function myfunction(callbackfunction) {
callbackfunction();
}
myfunction(aFunction);
However, as other answers have pointed out, is not necessary, since you can directly use the function name. I will keep the answer as is, because of the discussion that follows in the comments.
I will do something like this
var callbackfunction = function(param1, param2){
console.log(param1 + ' ' + param2)
}
myfunction = function(_function, _params){
_function(_params['firstParam'], _params['secondParam']);
}
Into the main code block, It is possible pass parameters
myfunction(callbackfunction, {firstParam: 'hello', secondParam: 'good bye'});
callbackfunction = () => {}
callbackfunction2(){
}
function myfunction1(callbackfunction) {
callbackfunction();
}
//Exe
myfunction1(callbackfunction);
myfunction1(callbackfunction2.bind(this));
Super basic implementation for my use case based on some excellent answers and resources above:
/** Returns the name of type member in a type-safe manner. **(UNTESTED)** e.g.:
*
* ```typescript
* nameof<Apple>(apple => apple.colour); // Returns 'colour'
* nameof<Apple>(x => x.colour); // Returns 'colour'
* ```
*/
export function nameof<T>(func?: (obj: T) => any): string {
const lambda = ' => ';
const funcStr = func.toString();
const indexOfLambda = funcStr.indexOf(lambda);
const member = funcStr.replace(funcStr.substring(0, indexOfLambda) + '.', '').replace(funcStr.substring(0, indexOfLambda) + lambda, '');
return member;
}