Javascript: using eval() to load functions dynamically - javascript

I want to load more than one function dynamically:
var str = "function foo() {} function bar() {}";
var functions = eval(???);
functions.foo();
Can this be done with eval? I was only successful with a single function.

With eval. Not recommended.
var str = "function foo() { console.log('foo'); } function bar() { console.log('bar'); }";
eval(str);
foo();
You could use an object and put the functions inside. You can later add a function with assignment.
var functions = {
foo: function () { console.log('foo'); },
bar: function () { console.log('bar'); }
};
functions.foo();
functions.baz = function () { console.log('baz'); }
functions.baz();

eval will execute certain string but it will not return anything. So functions will be undefined
eval will also run the given string in current scope. So the parsed functions will not necessarily be created in global scope.
Sample:
var str = "function foo1() {console.log('foo1')} function bar1() {console.log('bar1')}";
var functions = eval(str);
console.log(functions);
foo1();
(function() {
var str = "function foo2() {console.log('foo2')} function bar2() {console.log('bar2')}";
var functions = eval(str);
foo2();
})()
try {
foo2();
} catch (ex) {
console.log(ex.message)
}
My suggestion, create a new JS file and load it dynamically.
Reference Links:
Why is using the JavaScript eval function a bad idea?
Eval is evil
Dynamically load a JavaScript file

var foo = '( function foo() {} )'
var bar = '( function bar() {} )'
declare function with variable, then use the eval
var result = eval(foo)
result variable get the result of the foo() function

With functions.foo(); you try to access the property foo of the object functions and this will give you an undefined.
Solution
You could replace you string of functions simply with an object like
var functions = {
foo: function() {},
bar: function() {}
}
This avoids also the usege of eval().
Now you can access each property with functions.<functionName>;. You can add propertys dynamicly at runtime in JavaScript. So there is no usecase for eval in your problem
Example
var functions = {
foo: function() { console.log('foo') },
bar: function() { console.log('bar') }
}
function addNewFunction(object, functionName, functionImplementation) {
object[functionName] = functionImplementation
}
addNewFunction(functions, 'ok', function() { console.log('ok') })
functions.foo()
functions.ok()

Related

How to get the current running function name when declared with "foo = function(){...}"?

In this situation, arguments.callee.name get nothing.
foo = function(){
console.log(arguments.callee.name);
}
Is there any solution?
You didn't name it, thus it has no name.
foo = function(){
return (arguments.callee.name);
};
bar = function foobar() {
return (arguments.callee.name);
};
function foobar () {
return (arguments.callee.name);
}
console.log(foo()); //""
console.log(bar()); //"foobar"
console.log(foobar()) //"foobar"
The difference between foo() and foobar() is that foo() is a function expression, whereas foobar() is a declared function. The difference between foo() and bar() and is that one has a name, the other doesn't. Both are function expressions. Declared functions need a name, function expressions do not. See this canonical question for more info:
var functionName = function() {} vs function functionName() {}

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();
};

JavaScript object returning static method and himself as method

Is there a way to do:
foo() // return string "foo"
foo.bar() // return string "bar"
?
I tried to experiment with functions and objects. But nothing happened.
function foo() {
return "foo";
}
foo.bar = function() {
return "bar";
};
Or, if you prefer:
var foo = function() {
return "foo";
};
foo.bar = function() {
return "bar";
}
JS functions are a type of object so you can assign properties/methods to them the same as for any other object.
You can call either a function or a class named foo but you can't have both as far as I know. Correct me if I'm wrong. Why would you want a class and a function with the same way anyway? I'm assuming that that's what you want as there is little info in your post
To define a function use this
function foo() {
console.log("foo");
}
And call it like in your example.
To define a class do it like this (here are some other ways to do it).
var foo = {
bar: function() {
console.log("bar");
}
}
And again, call it like you did in your example.

Function Objection Notation?

I was wondering whether there is any performance / advantage of writing javascript in this format ?
var myFuncs = {
var firstFun = function() {
// do something
},
var secondFunc = function() {
// do something
},
var thirdFunc = function() {
// do something
}
}
So they can be called like
myFuncs.firstFun();
I'm trying to understand how this is more advantageous [other than code readability] ?
Function vs Object declaration
You can't use that particular syntax, the correct form is:
var myFuncs = {
firstFn: function () {},
secondFn: function () {},
...
};
The advantage to writing functions within an object has to do with namespacing and context. If you wrote:
var firstFn = function () {};
-or-
function firstFn() {}
the function would be defined at window.firstFn. Adding the functions on myFuncs makes the functions accessible at window.myFuncs.firstFn. If you want your JavaScript to work with other scripts you wouldn't want to have your foo function conflict with someone elses foo function:
<script src="a.js">
function foo() {...}
</script>
<script src="b.js">
function foo() {...} //this script would overwrite the foo function in a.js
</script>
<script src="c.js">
var bar = { //this script would be accessed at bar.foo()
foo: function () {..}
}
</script>
The calling context (this) of the function will also be different:
function foo() {
console.log(this); //window
}
var bar = {
foo: function () {
console.log(this); //bar object
}
}
Closure Syntax
What you may be getting confused with is the syntax for declaring functions within a closure:
(function () {
var foo = function () {...};
foo();
}());
In this case the closure is used to prevent the function from polluting the global scope (window.foo will not be set). This allows multiple scripts to use the same function names without worrying about being overridden.
OOP Syntax
The object syntax is often used to define the prototype for a JavaScript "constructor". In JS all functions can be called as a constructor simply by using the new keyword when the function is called:
function foo() {...}
var f = new foo(); //don't do it this way
For readability/maintainability/consistency you should always name your constructor using PascalCase:
function Foo() {...} //tells other developers this is a constructor
function bar() {...} //tells other developers this is a function
var f = new Foo();
var b = bar();
Without getting too lost in the details of how prototype works, you can assign methods to be shared across every instantiated object of a function by assigning an object to the function's prototype property:
function Foo() {...}
Foo.prototype = { //note the use of the object declaration for the functions
bar: function () {...},
baz: function () {...},
...
};
var f = new Foo();
f.bar(); //calls the bar function that was defined in the prototype
I think what you're asking is for advantages between declaring all of your functions globally, vs putting them all into an object. There is no performance difference. The main reason why people generally suggest adding them all into an object is to not clutter up the global space.
Think about it this way. If you create a global function named init in a javascript library, and make it global. Then if someone else does the same, it will overwrite your init. But, if you put it in an object named someJSLibrary, the odds of some other code overwriting your functions are much less.

How do I access these JavaScript member functions from outside?

I know how to access the below member function when it's written like this:
var blady_blah=
{
some_member_function: function ()
{
}
}
I access it from outside doing blady_blah.some_member_function()
But how do I access the member function when it's written like this:
(function() {
some_member_function: function ()
{
}
})();
Braces, { }, are used to define both object literals and function bodies. The difference is:
var name = {}; // Object literal
Which you may also see written as
var name = {
};
That's just the same but with some space in between so it's still an object literal, and unfortunately it looks very similar to:
var name = function () { // Function body
};
An object can have members:
var name = {
member: "string"
};
Whereas a function cannot; a function has statements:
var name = function () {
do_something();
var result = do_something_else();
};
You can't write
var name = function () {
member: "string"
};
Because you've mixed the two uses of { } together.
A variable can be defined within a function, but it can't be seen outside the function - it's within the function scope:
var name = function () {
var something_useful = string;
};
The second example is a closure (it just happens to have a syntax error inside). Minus the bad syntax, your self-evaluating anonymous function looks like this:
(function() {
})();
If you'd like, you can define functions inside this that will be invisible to the outside world. This is useful if you're interested in maintaining a clean global namespace, for example with library code.
(function() {
function utilityFunctionFoo() {
}
function utilityFunctionBar() {
}
})();
Of course, if you'd like to call any of these functions from the outside world, you're out of luck. Or are you? Actually, there's another way to define a function:
var foo = function() {
}
That's exactly the same as writing:
function foo() {
}
...Except that when written in the second style, you can actually omit the var keyword and create a global variable! Bringing it all together:
(function() {
publicData = "stuff accessible from outside anonymous function";
var privateData = "stuff that stays inside anonymous function";
function utilityFunctionFoo() {
}
function utilityFunctionBar() {
}
usefulFunctionExport = function() {
utilityFunctionFoo();
utilityFunctionBar();
}
})();
usefulFunctionExport();
You can't access it after the function it's in terminates. It's a local variable that goes out of scope when its parent function ends.
You should make the main function be a constructor so that it returns a new instance of a class (you could name it Blahdy_blah) with the member function as one of its properties.
Look up constructors, their return values, and accessing member variables.
If you want to execute the function you need to return an object that exposes the function.
var LIB = (function() {
    var fn = {
member_function : function(){}
};
return fn;
})();
and to call
LIB.member_function();
(function() {
blady_blah.some_member_function();
})();
If you need to add stuff into it you would write it like this.
(function() {
blady_blah.some_member_function(function(){
// Do stuff...
});
})();

Categories

Resources