How to run string as function inside a function in javascript? - javascript

An example of this question is like this
var bar = (function(){
function foo(){
alert("foo");
}
function test(){
var f = "foo";
// I want to run f() to run the function foo
}
})();
If the function is in the global scope I can run it using window["foo"]() or if namespaced window["namespace"]["foo"]() but how can I run it inside like the example? I don't want to use eval().
A much clear example of what I want is like this:
var fns = ['a','b','c'],
bar = (function(){
function a(){
alert("a");
}
function b(){
alert("b");
}
function c(){
alert("c");
}
function test(array){
for(var i;i<array.length;i++){
//I want to run the functions that is on the array
// something like window[array[i]]() if function is in the global scope
}
}
return {
test : test
}
})();
bar.test(fns);

You can create a local object to reference the function, then access its property as you would with your window example.
var bar = (function(){
function foo(){
alert("foo");
}
var obj = {
foo: foo
};
function test(){
var f = obj["foo"];
f();
}
test();
})();
That's as close as you're going to get in a local scope without using eval.

You can create the object OR fn with this operator and make it an function with new constructor.
Creating an object.
https://jsfiddle.net/0Lyrz6rm/6/
var bar = {
foo: function(){
alert("foo");
},
test: function(){
var f = "foo";
return f;
}
}
bar["foo"]();
console.log(bar["test"]());
Another alternate way is to define the function as with constructor and little modification.
https://jsfiddle.net/0Lyrz6rm/4/
var bar = function(){
this.foo = function(){
alert("foo");
};
this.test = function(){
var f = "foo";
return f;
// I want to run f() to run the function foo
}
this.test2 = {
f: "foo"
}
}
var f = new bar();
f["foo"]();
console.log(f.test());
console.log(f.test2.f);

Related

Apply/Call method in Javascript: What is the first arguments "this"?

I am confused about using apply or call method correctly.
I know that apply is passing an array to the function and call is passing strings to a function.
For example the code below, what does "this"really have to do with the code? if it has nothing to do with this code, then can anyone give me an example when "this" is implementing appropriately?
function myFunction(a, b) {
return a * b;
}
myArray = [10,2];
myFunction.apply(this, myArray);
It's the context for the function. If you have this.something inside the function, it will access that particular property from that context object.
function foo(bar) {
this.bar = bar;
}
foo.apply(this, ['Hello']); //calling foo using window as context (this = window in global context in browser)
console.log(this.bar); //as you can see window.bar is the same as this.bar
console.log(window.bar);
var ctx = {}; //create a new context
foo.apply(ctx, ['Good night']);
console.log(ctx.bar); //ctx now has bar property that is injected from foo function
Open up your dev console to see result.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
this is the scope of the Apply/Call function. An example is:
function test() {
alert(this.a);
}
(function () {
this.a = "test";
test();//test
var self = this;
(function () {
this.a = "Foo";
test();//Foo
test.apply(self, []);//test
}());
}());
The first argument will be the this in your function.
ie:
var p = {"name":"someone"};
function myFunction(a, b) {
console.log(this);
return a*b;
}
var myArray = [10,2];
myFunction.apply(p, myArray); //log output shows {"name":"someone"}

Access of function in jQuery scope

I want to build a function outside a jQuery scope:
(function($) {
function MyObject() {
console.log('foo');
};
}(jQuery));
var $my_object = new MyObject();
But function MyObject is not accessible :
ReferenceError: MyObject is not defined
However, if i build my function in the scope, it's working:
(function($) {
function MyObject() {
console.log('foo');
};
var $my_object = new MyObject();
}(jQuery));
foo
How access to MyObject outside the scope ?
I would probably not recommend it but you can basically do what you want by returning the functions as part of an object and assigning the IIFE to a variable like this
var library = (function ($) {
var exports = {};
var private = 'see you cant get this';
var MyObject = exports.MyObject = function (_in) {
console.log(_in);
};
var another_func = exports.sum = function (a, b) {
console.log(a + b);
};
return exports;
}(jQuery));
library.MyObject('foobar'); // "foobar"
library.sum(3, 5); // 8
console.log(private); // Uncaught ReferenceError: private is not defined
Although I don't know why you want to do it.. Maybe this helps
// Define Class globally
// window.MyObject also works
var MyObject = (function($) {
// Passes jQuery in
return function () {
console.log('foo');
};
}(jQuery));
var $my_object = new MyObject();

Double nesting a function-valued return stops from entering the double nested function

Trying to understand the scope chain and execution context stack articles from David Shariff's Blog, I've tried to understand closures here
function foo() {
var a = 'private variable';
return function bar() {
alert(a);
}
}
var callAlert = foo();
callAlert(); // private variable
I just wanted to test if inner function has the variable object just from its parent or from the whole scope chain, so I added a nested function repeating the example:
function foo() {
var a = 'private variable';
return function bar() {
return function foobar() {
console.log(a);
};
};
}
var callAlert = foo();
callAlert(); //
And that is not giving any result. It seems the interpreter is not even entering the foobar() function. And the syntax is the same than its parent.
But it works if I divide the function declaration and execution.
function foo() {
var a = 'private variable';
return function bar() {
function ra() {
console.log(a);
};
return ra();
};
}
var callAlert = foo();
callAlert(); // private variable
And really I'm trying to guess why; where's the difference from bar() and foobar() functions.
PS - I'm testing on JSFiddle
function foo() {
var a = 'private variable';
return function bar() {
return function foobar() {
console.log(a);
};
};
}
Here you're returning a function that returns a function, so you need to call that new, doubly nested function
var callAlert = foo()();
DEMO
Or any variation on that theme
var getBar = foo();
var getFooBar = getBar();
getFooBar(); //private variable.
Updated demo
The second example works fine because you're still returning one function—a function that simple calls another function.
return function bar() {
function ra() {
console.log(a);
};
return ra();
};

How to extend an object inside an anonymous function

I want to add another function called myFunction() into the CoreTeamObject, which is declared as local inside the anonymous function. Is this possible?
!function ($) {
var CoreTeamObject = function () {
var coreTeamVar1; // ...
this.someState = false; // ...
coreTeamFunction: function () { /* ... */ }
};
}(window.jQuery);
Normally, I'd use prototype with something like:
CoreTeamObject.prototype.myFunction = function(){
return
};
But I simply don't know how to access the object.
You simply can't. Variables within a function are private and cannot be accessed from the outside.
! function () {
var foo = 1;
}();
// Calling `foo` will throw a referenceError here.
// It doesn't even work with classes...
var foo = function () {
var bar = 2;
};
var bax = new foo();
// `bax.bar` doesn't exist.
However, there are workarounds. You could store them in a global variable (bad idea, though):
! function (w) {
w.foo = 3;
}(window);
// window.foo = 3
// foo = 3
Or if you can rewrite it to a class:
var foo = function () {
this.bar = 4;
};
var bax = new foo();
// bax.bar = 4
I hope this helps.

Creating global API object

I'm using the module-via-anonymous-function-pattern in java-script to have an anonymous function that embodies the whole module and exposes specific public API parts by setting a global property.
I tried several methods of setting such a global property and the second one posted below fails:
window.foo = (function() {
function bar() { this.hello = "world" }
return new bar();
})();
> foo.hello
"world" // OK
vs.
(function() {
window.foo2 = new bar( this.hello = "world" );
function bar() {}
})();
> foo2.hello
undefined // Fail
Why is the second method not creating a proper bar-object?
In your 2nd method:
(function() {
window.foo2 = new bar( this.hello = "world" );
function bar() {}
})();
this is the window, and
new bar(this.hello = "world")
is equal to
window.hello = "world";
new bar(window.hello);
you can check it here
And I think what you want is :
(function() {
window.foo2 = new bar( "world" );
function bar(a) {this.hello = a}
})();
see here
you should try the code below
(function() {
function bar() { this.hello = "world"; };
window.foo2 = new bar();
})();
The problem is the way to use construct an object. Try this two ways.
window.foo2 = new bar();
function bar() {this.hello = "world";};
or
window.foo2 = new bar("world");
function bar(x) {this.hello = x;};

Categories

Resources