What's the best way to replace eval? - javascript

I deal with a JavaScript code to improve.
The idea here is to invoke functions dynamically.
Here is the code to replace:
//this.actionCallback return the name of the function to invoke
eval(this.actionCallback + "('testArgument')");
What is the best way to replace it:
This way:
window[this.actionCallback]("testArgument");
Or this way:
var actionToCall = this.actionCallback+'("testArgument");';
var functionToInvoke = new Function(actionToCall);
functionToInvoke();
Or is there is a better way to do this?

The first way is a much better method - new Function(actionToCall) is just eval in disguise.

Both of the alternatives you have mentioned are not equivalent to the first one:
Your first alternative requires that the function name be the member of window (in other words, defined at global scope). Having a function inside another scope will cause this to fail, but it doesn't use eval. :)
Your second alternative creates a function object using the Function() constructor, so this also only works when the function in declared at the global scope, because a function defined by a Function constructor does not inherit any scope other than the global scope, and as said in Jamie Wong's answer, using the Function() constructor is still considered as eval :(
Here is an alternative that should work like your first one, but looks slightly better, but still uses eval.
eval(this.actionCallback)("testArgument");
But the best way is that this.actionCallback should be a real function object, and not just a function's name, then you can call:
this.actionCallback("testArgument");

I would suggest using window[this.actionCallback]("testArgument");.
This way there is no evaling or making anonymous functions. You are just calling the function directly.

In case like this you probably do not want to allow calling arbitrary functions, only "action" functions.
Build a list of supported callbacks
actionCallbacks["doWork"] = doWork;
Call them
actionCallbacks[this.actionCallback]("testArgument")
And catch if function does not exist

If the function belongs to an object you can do something like this:
function run(func, object, args = []) {
object[func]().apply(object, args);
}
Also, here is unique (but not very reliable) way of replacing eval:
function evaluate(code) {
location.href = "javascript:" + code;
}
evaluate("alert(1)");

Related

Is there a way to evaluate a function defined as a string by using eval()?

I would like to store a function definition in a string, like for example:
var funcString = 'function(){ return 4+4 }'
Can I use eval() to evaluate the function?
Like for example:
var result = eval(funcString)
which will evaluate the string in funcString as a function and return 4+4 (8) in result.
edit: So from what you've told me I understood that I shouldn't use eval in that way, but for my case I don't think there is another way.
I would like to define a set of rules in a separate file and I want to instruct my Javascript Library to look into this file and search for the rules. The following is an example of a rule:
rule('logOut', (function() { return !JSLibrary.compareUserDetails })(), (function() { console.log("\n\nError: logged out user did not match\n\n\n") })())
I would like to evaluate both of the functions defined in the rules and I think that eval is the only way to do it. I don't know if there exist any other.
Fair warning, eval is "evil." I'll answer your question regardless, but you might want to rethink using eval.
In JavaScript, functions are values, just like 5, 'Stack Overflow' and document. In fact, what function myFunction(args) { body } does is create a function and throw it into a variable called myFunction*.
Say you wanted to take that function and put it into another variable. You can just say var otherVariable = myFunction. And if you want to call that function, you can just say otherVariable().
But say you want a function that isn't bound to a name, for instance if you're passing it to another function. You can use an anonymous function, defined as function(args) { body }. That's what's inside the string you're eval-ing. Anonymous functions are just like any other function, and you can call them as such. Actually, you can even call them right out of the result of eval by tacking on some parentheses at the end.
Unfortunately, it's not that easy though. You can't just write a line of code with an anonymous function definition and expect it to run: you will instead get an error complaining about it not being named. To fix this, throw some parenthesis around the definition to force it to be an expression instead of a statement.
Your final working code will look like this:
var funcString = '(function(){ return 4+4 })'
var result = eval(funcString)()
Sure, you should never use eval for this particular use, but I hope you learned a bit about JavaScript from this answer anyways.
* There's more to it than that, such as hoisting, but that doesn't really matter in this explanation.
Use of an immediately invoked function expression can call a function with eval.
document.body.innerHTML = eval('(function(){return 4+4;})()');
WARNING: do not ever do this: it's insecure, a performance-killer, harder to read/understand, etc

What is difference between function FunctionName(){} and object.FunctionName = function(){}

Today while working my mind was stack at some point in javascript.
I want to know that what is basic difference between
function FunctionName(){
//Code goes here;
}
And
var MyFuncCollection = new Object();
MyFuncCollection.FunctionName = function(){
//Code goes here;
}
Both are working same. Then what is difference between then. Is there any advantage to use function with object name?
I have read Question. But it uses variable and assign function specific variable. I want to create object and assign multiple function in single object.
The first one defines a global function name. If you load two libraries, and they both try to define FunctionName, they'll conflict with each other. You'll only get the one that was defined last.
The second one just has a single global variable, MyFuncCollection. All the functions are defined as properties within that variable. So if you have two collections that try to define the same function name, one will be FuncCollection1.FunctionName, the other will be FuncCollection2.FunctionName, and there won't be any conflict.
The only conflict would be if two collections both tried to use the same name for the collection itself, which is less likely. But this isn't totally unheard of: there are a few libraries that try to use $ as their main identifier. jQuery is the most prominent, and it provides jQuery.noConflict() to remove its $ binding and revert to the previous binding.
The short answer is, the method in object context uses the Parent Objects Context, while the "global" function has its own object context.
The long answer involves the general object-oriented approach of JavaScript, though everything in JavaScript is an object you may also create arrays with this Method.
I can't really tell you why, but in my experience the best function definition is neither of the top mentioned, but:
var myFunction = function(){};
It is possible to assign function to variables, and you may even write a definition like this:
MyObject.myMethod = function(){};
For further reading there are various online Textbooks which can give you more and deeper Information about this topic.
One main advantage I always find is cleaner code with less chance of overwriting functions. However it is much more than that.
Your scope changes completely inside the object. Consider the following code ::
Function:
function FunctionName(){
return this;
}
FunctionName()
Returns:
Window {top: Window, location: Location, document: document, window: Window, external: Object…}
Object:
var MyFuncCollection = new Object();
MyFuncCollection.FunctionName = function(){
return this;
}
MyFuncCollection.FunctionName()
Returns:
Object {}
This leads to some nice ability to daisy chain functions, amongst other things.
The first:
function functionName (){
//Code goes here;
}
Is a function declaration. It defines a function object in the context it's written in.
Notice: this doesn't have to be the global context and it doesn't say anything about the value of this inside it when it's invoked. More about scopes in JavaScript.
Second note: in most style guides functions are declared with a capitalized name only if it's a constructor.
The second:
var myFuncCollection = {};
myFuncCollection.functionName = function () {
//Code goes here;
};
notice: don't use the new Object() syntax, it's considered bad practice to use new with anything other then function constructors. Use the literal form instead (as above).
Is a simple assignment of a function expression to a property of an Object.
Again the same notice should be stated: this says nothing about the value of this when it's invoked.
this in JavaScript is given a value when the function object is invoked, see here for details.
Of course, placing a function on an Object help avoiding naming collisions with other variables/function declarations in the same context, but this could be a local context of a function, and not necessarily the global context.
Other then these differences, from the language point of view, there's no difference whatsoever about using a bunch of function declarations or an Object with bunch of methods on it.
From a design point of view, putting methods on an Object allows you to group and/or encapsulate logic to a specific object that should contain it. This is the part of the meaning of the Object Oriented Programming paradigm.
It's also good to do that when you wish to export or simply pass all these functions to another separate module.
And that's about it (:

Declare javascript function with extra properties in a single statement?

I know I can define properties on functions, which can then be accessed from within the function. Right now, the only syntax I can work out involves two statements. Is there a more concise way to express the following:
function myFunc() {
// do some work
}
myFunc.myProp = 0;
I'm not looking for a solution that is fewer characters -- this isn't code golf. I'm asking something more along the lines of "are there different patterns of function declaration that have this other desirable merit?" This is almost about ways to use closures (because I suspect the answer lies there).
Thanks!
Especially if you want to access properties of the function from inside the function itself, you're better off doing this:
var theFunction = function() {
function theRealFunction() {
// the code
if (theRealFunction.something == "not whatever")
// do something
// more code
}
theRealFunction.something = "whatever";
return theRealFunction;
}();
What that does is wrap your function declaration up in an anonymous function. The problem with accessing function properties via the function name is that it must do that by finding the function's name in the surrounding scope. That's kind-of icky, but at least this way it involves a scope that's essentially private. It'll work whether or not the resulting function (returned as the return value of the anonymous function) is assigned to a different variable, passed to a function as a handler function, etc.
This really, really all depends. If you're looking for private variables, then you can easily return a function from the function -- an inner-function will contain access to its parent's scope.
var outer_function = (function () {
var private_var = "secret",
public_var = "public",
inner_function = function () {
return private_var;
};
inner_function.public_var = public_var;
return inner_function;
}());
outer_function now equals inner_function, with the benefit of having access to the enclosed data. Any properties attached to the inner (in the way you did) will now be accessible as public properties of outer.
To this end, you can return, say, a constructor for a class, with public-static properties, with the enclosed vars acting as private-static properties, shared between every instance of the "class" you build.
Not exactly the answer to your question, but if you ever want to read up some different design patterns that can be used when defining a javascript function, this is one of the best articles I've ever read on the topic:
http://www.klauskomenda.com/code/javascript-programming-patterns/

when to use Function in javascript?

I have been writing javascript for one or two months , I never used Function keyword , like Function.method(); when I define function , I simply define it as :
function fooBar () {};
Can you give me an example when using Function is more convenient ?
You shouldn't use the Function constructor so often, it basically uses code evaluation to build a function.
It requires string arguments, being the last argument the function body, and the previous ones will be the arguments of the new function itself, for example:
var add = new Function("a", "b", "return a + b;");
add(5,5) == 10;
When you should use it?
As I said not so often, I personally try to avoid them since they use code evaluation.
A thing to note is that no closures are created when functions are built in this way, which can be a good thing for some performance circumstances, for example to shorten the process of identifier resolution, but you should use them with care...
Every function in JavaScript is
actually a Function object.
Read Function
Function objects created with the
Function constructor are parsed when
the function is created. This is less
efficient than declaring a function
and calling it within your code,
because functions declared with the
function statement are parsed with the
rest of the code.
function view(){
document.getElementById('one').innerHTML="New Text here";
}
this function can you call from either keyboard events of mouse events

Javascript: Calling a function written in an anonymous function from String with the function's names withoout eval?

Update2:
What I really wanted to ask was already argued in a different page. Please check the following entry. (Thanks to BobS.)
How can I access local scope dynamically in javascript?
Hello.
I've started using jQuery and am wondering how to call functions in an anonymous function dynamically from String.
Let's say for instance, I have the following functions:
function foo() {
// Being in the global namespace,
// this function can be called with window['foo']()
alert("foo");
}
jQuery(document).ready(function(){
function bar() {
// How can this function be called
// by using a String of the function's name 'bar'??
alert("bar");
}
// I want to call the function bar here from String with the name 'bar'
}
I've been trying to figure out what could be the counterpart of 'window', which can call functions from the global namespace such as window["foo"].
In the small example above, how can I call the function bar from a String "bar"?
Thank you for your help.
Update:
Here's what I want:
Define functions that are only used in the closure.
Avoid creating an Object in the closure that holds those functions in order to be accessed as obj['bar'].
Avoid eval (if possible) in order to write code more simply in a straightforward manner (if exists).
Decide function's name dynamically via the URI parameter or anything variable.
Being a newbie of Javascript, I thought 'this' would be the counterpart of 'window' in the closure, and tried writing:
// in the closure
name = 'bar';
this[name]; // undefined ...
and failed (of course...).
All of these are for pursuit of further laziness. Javascript is kind of new to me and currently I've been trying to write code as lazy as possible.
As Kobi wrote, eval might be a good option. Alternatively, is there any reason not to do
$(function(){
var localNamespace = {};
function bar() {
alert("bar");
}
localNamespace['bar'] = bar;
// Now bar() can be called by, well, localNamespace['bar']
}
Update:
Similar SO entries, such as How can I access local scope dynamically in javascript?, seem to indicate you're out of luck without using one of these two approaches or something even uglier.
Inside your ready function:
window.bar = function bar() {
// ...
}
Then, you can access window['bar'].

Categories