Calling nested function when function name is passed as a string - javascript

I'm trying to access a nested function by passing the function name in as a string and then calling it. Eg, see this post
function outer(action){
window["outer"][action]();
function inner(){
alert("hello");
}
}
outer("inner");
However it doesn't work. Error:
window.outer[action] is not a function
How to make this work, or an alternative way of calling a nested function.
The reason for this is that I am trying to hide a bunch of functions that are called by an iframe inside a functions scope.

function outer(action){
var inner = {
func1: function() {},
func2: function() {},
func3: function() {},
// ...
}
inner[action]();
}
outer("func1");

In that way you are trying to access the "inner" property of the "outer" function (outer.inner) that is not defined. The only way to do that is by using eval:
function outer(action){
eval(action+"()");
function inner(){
alert("hello");
}
}
outer("inner");
But remember eval is evil is some situations so be careful.

Related

Why can't I access a returned function with the dot syntax

I though that once createFunction runs I'll have access to the inner function.
function createFunction() {
function printHello() {
return console.log("hello");
}
return printHello;
}
// Both of these return undefined
createFunction(printHello());
createFunction.printHello();
Any thoughts?
Proper syntax is:
createFunction()();
... or, a bit more wordy:
const returnedFunction = createFunction();
returnedFunction();
... as printHello name makes any sense only within createFunction, but its value is actually returned by that function. And yes, it's perfectly ok to place any number of () in sequence you want.
As a sidenote, returning the result of console.log('hello') makes little sense: logging itself is a side effect, no need to check its result.
I though that once createFunction runs I'll have access to the inner function.
No, you cannot access a variable that is inside of a function outside of it. If you call a function those variables exist, but you cannot access them. However if a value gets returned, you can work with the function call as if it would be that expression. In your case you return the function so you can access it as:
var print = createFunction();
print();
Or as a oneliner:
createFunction()();
In your code createFunction returns another function, so to execute inner function you must call inner function by appending () after return value of createFunction i.e createFunction()();
createFunction() give printHello = function definition
createFunction() () same as printHello**()**
Also if we simplify your code we can re-write as
function printHello() {
console.log("hello");
};
function createFunction() {
return printHello;
};
console.log("return value of: createFunction()");
console.log(createFunction());
console.log("return value of: createFunction() () --> printHello()");
createFunction()();

JavaScript Method within Method

I would need to declare Methods within Methods and call them outside as a Object, Method connotation...
To make it more clear:
I need to call:
Object.Method().nestedMethod();
how can I do it so? This failed so far:
function Object(){
this.Method = function(){
this.Method.nestedMethod = function(){
};
};
}
As I work on a DSL it is necessary to call a Method within a Method. In this case the last Method is some kind of recursion Method of the previous one, like this:
Object.execute(param).recursion();
How would I have to declare the nested Method to access this so?
You can return an object that contains nestedMethod:
Object.Method = function () {
return {
nestedMethod: function () {}
};
}

accessing a hidden function with javascript

Hi I have a few custom functions wrapped in jQuery's document.ready function. Most of these functions are utilized from within that function and work, but there is a case where I would like to access a function contained within this from the global scope. How can I do this? can i do something like:
jQueryReadyScope.myFunctionName('paramaters');
Thank you very much.
Nope, but you can name the function and pass it to .ready():
var myFunctionName = function (params) {
// do things
}
// pass as callback to ready function
jQuery(document).ready(myFunctionName);
// access directly like any other function:
myFunctionName('paramaters');
That's a scope issue, and all you need to do is specify the namespace. In this case, you're talking global so we'll use window.
window.myFunction = function() { ... stuff }
To access it from the global scope it would need to be assigned to a global variable, either by declaring it outside your document ready or by assigning it as a property of window:
var yourGlobalFunction1 = function() { ... }
$(document).ready(function() {
function privateFunction() { ... }
window.yourGlobalFunction2 = function() { ... };
yourGlobalFunction1();
privateFunction();
yourGlobalFunction2();
});
yourGlobalFunction1();
// and then at some later point AFTER the document ready has run,
// e.g., in response to some event:
$("#someelement").click(function() {
yourGlobalFunction2();
});

Running a custom function - settings.func is not a function

I have written a jQuery plugin which I want to call a custom function on like so...
(function($) {
$.fn.testPlugin= function(options) {
var settings = {
func: null
};
if (options) {
$.extend(settings, options);
}
settings.func();
};
})(jQuery);
In this case I want to run the doSomething function.
$(document).ready(function(){
$('div').testPlugin({
func: 'doSomething'
});
});
function doSomething() {
alert('hello');
}
I always get the error settings.func is not a function so I am having to use:
eval(settings.func+"()");
Intead of:
settings.func();
Which is not ideal! Any ideas why I am getting this?
Because you're assigning a string to settings.func, not a function. Strings are never functions, even if they contain the name of a function.
Functions are first-class citizens, however, which means you can use them as you would any other variable, assigning them to variables or passing them as arguments to other functions. Change:
$('div').testPlugin({
func: 'doSomething'
});
to
$('div').testPlugin({
func: doSomething
});
and it should work.

How to execute a YUI function from Javascript?

How can i call a YUI function that is wrapped inside a YUI().use from javascript?
example
Below is a YUI function "runShowAnim" which executes animShow.run(); for an animation effect...
var runShowAnim = function(e) {
animShow.run();
};
I want this effect to happen when i validate something in a javascript function. I tried to call it as below. But it doesn't seem to work.
function notifyUser(message) {
document.getElementById("msgArea").innerHTML = message;
runShowAnim();
}
I achieved this by sandwiching the YUI function completely inside a function and calling that function..
var runShowAnim = function() {
YUI().use('anim', 'node', function(Y) {
var animShow = new Y.Anim({
node: '#msgArea',
to: { height: 50,opacity:1 }
});
animShow.run();
});
};
now i can call runShowAnim without any problem like in the below sample function..
function notifyUser(message) {
document.getElementById("msgArea").innerHTML = message;
runShowAnim();
}
If you want to call a function, you have to suffix the function name with () and include 0 or more comma separated arguments between them.
runShowAnim();
If the function doesn't have global scope (as yours will have if it is declared inside a function passed to use()) and not passed outside in some way then you can only do this from the same scope.
I think you're missing the parentheses.
function notifyUser(message) {
document.getElementById("msgArea").innerHTML = message;
runShowAnim(); // right here
}
YUI.thefunction()?
I think you need to call it with namespace too
something similar to
var X = function(){};
X.Y = function(){};
X.Y.Z = function(){};
X.Y.Z.foo = function(e){alert(e);}
//foo("me");<-error
X.Y.Z.foo("me");
If you want to call a function that has been defined inside the closure (the function passed as the last parameter to YUI.use) from outside it, you need to expose the function globally.
Either define a global variable outside the closure and assign your function to it, or assign your function to the window object
i.e.
var runShowAnim;
YUI().use(function(e){
runShowAnim = function(){alert('called');}
});
runShowAnim();

Categories