I have a function that is written on the client side, send to a server as a string, and executed there.
Inside this function I use some, primitive, variable of the client. An example could be
function (obj){
return obj.number == aNumber;
}
where aNumber is an integer variable on the client side, while obj is an object living on the server.
The problem is that being the function executed on the server, the server doesn't have any aNumber variable there, so what I would like to do is to replace aNumber with his actual value, but I don't know how to do that, since the code of the function is actually never executed on the client.
Is there any solution (that possibly doesn't involve parsing the function as String)?
It seems a trivial question but I couldn't find a solution at all.
Since aNumber only exists on the client, that's the only place you can do this.
You can do a substitution (on the client):
var functionString = theFunction.toString();
functionString = functionString.replace(/\baNumber\b/g, aNumber);
...and then send functionString to the server. That assumes this code is running in a context that has access to aNumber, as the function being turned into a string does; and that aNumber is really a number.
But this is a seriously bad idea. Stepping back from the details and looking at the broader picture, I'm sure there's a solution that doesn't involve sending a function to the server to be executed there.
Related
Eclipse has an option to warn on assignment to a method's parameter (inside the method), as in:
public void doFoo(int a){
if (a<0){
a=0; // this will generate a warning
}
// do stuff
}
Normally I try to activate (and heed) almost all available compiler warnings, but in this case I'm not really sure whether it's worth it.
I see legitimate cases for changing a parameter in a method (e.g.: Allowing a parameter to be "unset" (e.g. null) and automatically substituting a default value), but few situations where it would cause problems, except that it might be a bit confusing to reassign a parameter in the middle of the method.
Do you use such warnings? Why / why not?
Note:
Avoiding this warning is of course equivalent to making the method parameter final (only then it's a compiler error :-)). So this question Why should I use the keyword "final" on a method parameter in Java? might be related.
The confusing-part is the reason for the warning. If you reassign a parameter a new value in the method (probably conditional), then it is not clear, what a is. That's why it is seen as good style, to leave method-params unchanged.
For me, as long as you do it early and clearly, it's fine. As you say, doing it buried deep in four conditionals half-way into a 30-line function is less than ideal.
You also obviously have to be careful when doing this with object references, since calling methods on the object you were given may change its state and communicate information back to the caller, but of course if you've subbed in your own placeholder, that information is not communicated.
The flip side is that declaring a new variable and assigning the argument (or a default if argument needs defaulting) to it may well be clearer, and will almost certainly not be less efficient -- any decent compiler (whether the primary compiler or a JIT) will optimize it out when feasible.
Assigning a method parameter is not something most people expect to happen in most methods. Since we read the code with the assumption that parameter values are fixed, an assignment is usually considered poor practice, if only by convention and the principle of least astonishment.
There are always alternatives to assigning method parameters: usually a local temporary copy is just fine. But generally, if you find you need to control the logic of your function through parameter reassignment, it could benefit from refactoring into smaller methods.
Reassigning to the method parameter variable is usually a mistake if the parameter is a reference type.
Consider the following code:
MyObject myObject = new myObject();
myObject.Foo = "foo";
doFoo(myObject);
// what's the value of myObject.Foo here?
public void doFoo(MyObject myFoo){
myFoo = new MyObject("Bar");
}
Many people will expect that at after the call to doFoo, myObject.Foo will equal "Bar". Of course, it won't - because Java is not pass by reference, but pass by reference value - that is to say, a copy of the reference is passed to the method. Reassigning to that copy only has an effect in the local scope, and not at the callsite. This is one of the most commonly misunderstood concepts.
Different compiler warnings can be appropriate for different situations. Sure, some are applicable to most or all situations, but this does not seem to be one of them.
I would think of this particular warning as the compiler giving you the option to be warned about a method parameter being reassigned when you need it, rather than a rule that method parameters should not be reassigned. Your example constitutes a perfectly valid case for it.
I sometimes use it in situations like these:
void countdown(int n)
{
for (; n > 0; n--) {
// do something
}
}
to avoid introducing a variable i in the for loop. Typically I only use these kind of 'tricks' in very short functions.
Personally I very much dislike 'correcting' parameters inside a function this way. I prefer to catch these by asserts and make sure that the contract is right.
I usually don't need to assign new values to method parameters.
As to best-practices - the warning also avoids confusion when facing code like:
public void foo() {
int a = 1;
bar(a);
System.out.println(a);
}
public void bar(int a) {
a++;
}
You shoud write code with no side effect : every method shoud be a function that doesn't change . Otherwise it's a command and it can be dangerous.
See definitions for command and function on the DDD website :
Function :
An operation that computes and returns a result without observable side effects.
Command : An operation that effects some change to the system (for
example, setting a variable). An
operation that intentionally creates a
side effect.
So, lets say I have a string defined in javascript:
var s = "function();"
Can I execute the code if I know the value of the string?
And if yes, then can I have multiple commands inside a string? For instance:
var k = "function(); a = a + 1;"
Thanks in advance
You can use eval, and yes multiple statements will be executed. BUT, it is generally a bad idea to use eval. In most cases you can probably accomplish whatever you are trying to do without eval.
eval can be quite dangerous if used with user supplied code, such as something from a form or URL. It opens you up to Cross-Site Scripting (XSS) attacks. Just avoiding it is the best course of action, as this answer mentions, sanitizing input before putting it through eval is not at all straight forward and very error prone.
A couple of other less important problems with using eval are that it makes code hard to debug and it is slow. It makes it hard if not impossible for browsers to optimize and/or cache it like they do other code.
Update
I'm surprised I neglected to mention this when I originally answered this, but explicitly using the eval statement is not the only way eval can be invoked in JavaScript. Passing code instead of a function reference to setTimeout or setInterval will implicitly eval that code.
// This evals:
setTimeout("doSomething()", 1000);
// This does not eval:
setTimeout(doSomething, 1000); // also shorter :)
Although not exactly the same as eval, the Function constructor also has similar security concerns associated with it.
let xss = 'alert("XSS")';
// whatever is in the string passed to Function
// becomes the body of the function
let doSomething = new Function(xss);
document.querySelector('button').addEventListener('click', doSomething, false);
<button>Do Something</button>
Just as with eval, care should be taken when using strings as input for setTimeout, setInterval or the Function constructor, especially if user input is going to be passed into them.
Also see:
How evil is eval
Eval isn't evil, just misunderstood
Why is using the JavaScript eval function a bad idea? (Several good answers here)
Dynamic languages strike back
You can use eval() to Evaluate/Execute JavaScript code/expressions:
var k = "var a = 0; alert(a); a = a + 1; alert(a);"
eval(k);
The eval function will evaluate a string that is passed to it.
it is slow. This is because the code to be evaluated must be parsed on the spot, so that will take some computing resources.
I have a "library" of objects that I want to load on the fly from a database. Each object comes with its own special functions that are called at specific times depending on the objects type. Ideally I'd like to be able to do this, although its been pointed out that this doesn't work:
library = {
"myObj" : {"name" : "myObj", "type" : "myType", "function" : function () { } } //, etc
}
The string "myObj" is passed around my program quite a bit, but I only have to access certain values of the object at a time, and in some circumstances there's a specific function that needs to be run. The problem is that I'm looking at hundreds, and eventually thousands, of potential objects that could exist with varying functions.
What is the "right" way to store a function to be called like this. I know that calling eval can be very unsafe during execution, enabling xss attacks and whatnot. I really want to avoid a massive switch statement or the bloated loading of additional functions. I'd also like the solution to be as concise as possible.
This can't be the first time this has come up. ;/
Thanks for your help.
Just use eval to recreate the function after loading it as a string. So if you deserialize an object myObj from JSON, and you have a property:
myObj = {
....
function: "function() { ... }"
}
you can very easily turn it to a real function:
eval("myObj.func = " + myObj.func);
http://jsfiddle.net/kceTr/
Oh - I am not sure if that was an edit or I missed it before - but re: eval.
Eval is a tool. You want to store a function in a database. It really doesn't make much difference if you have to "eval" to turn it into code, or there was some other magic way to do it: if someone can change the data in your DB, then they can change a function.
If you need to store a function, then eval is your tool. It's not "bad" by nature, it's bad because it's easy to misuse. Whether you use it well or not is up to you.
Remember anything running on the client is still just running on the client. There's nothing a malicious person could do with eval, that they couldn't do with the Chrome debugger a lot more easily. Anyone can always run any code they want on the client, it's up to your server to decide how to handle what it receives. There's nothing safe on the client in the first place...
Changing the prototype of the object is a half thought I have.
You've got your library like
library = {
"myObj" : {"name" : "myObj", "type" : "myType", "function" : function () { } } //, etc
}
You've got an object (let's call it theObj) that you know is a myObj (due to a string maybe? property?)
theObj.__proto__ = library["myObj"];
That way you can execute
theObj.function(...);
jsfiddle example (it's rough!). Also, be careful with proto, it's deprecated (1) (2)
As to serializing the functions, can you get them in using a script tag that points to something serverside that slurps them from the db and returns the js? Just include them inline as you render the page (in a script block)? Or, if all else fails, eval should work, as long as you know that the functions you've got stored in the database are clean and safe.
There is no right way to do this, because its not generally a good idea.
HOWEVER, if you want to do it anyways you can simply extend the prototype of Function with a .toJSON method.
Function.prototype.toJSON = function(){ return this.toString(); }
Then you can simply use JSON.stringify and functions will be serialized as strings.
Its generally a not good idea in most cases. There are very few circumstances where you want to do this and even then, there is probably a better way.
A better approach might be to serialize the object's properties when you "sleep" it, and "waking" the object by reattaching its properties to a new instance of the object with the appropriate methods defined.
what you are doing with it is just fine. However, if i were you, for readability and tidyness, i would rather have the function created outside and simply have it assigned to your object key.
You don't need eval here. Instead do it this way whenever you want access to the stored function -
library.myObj.function()
You do your best in parameterising your functions, so that you end up
with as little typologies as possible.
Store them on the server in individual JS files, then load the needed file dynamically, by name.
In the JSON, only store the name of the file that contains the function that you need. And, of course, you will be caching already loaded files, to go easy on the server.
Just my two cents.
You can only really serialise a whole file with require calls in it. If you do that, you can create a module, exports and module.exports, eval the file with a function surrounding it and snag the module.exports out of it.
It's not exactly secure, but for that you need to use something like VM2 and value-censorship (which I've been working on) to avoid them calling eval() and owning your machine or the entire network.
The following code already exists in one of the javascript files i am working , may i know what does the following do
Its jquery ajax , i saw the response result and its a json string which is manually created by the backend.
I want to know what is eval doing here
success: function (response) {
var response= response.replace(/\\/g, "%5C");
eval(response);
},
eval executes the passed in string as if it were javascript code.
What exactly happens depends entirely on the contents of response.
That is, the value of the response variable that is passed to the eval function gets evaluated as normal javascript.
If response was "alert('Hello from evel!');", you would see an alert box with the text "Hello from evel!".
eval() executes a string as JavaScript code in the context of its execution context. Generally, this means scoped to whatever function it is in.
It is often used to evaluate a JSON string. Note that if you are eval()ing a JSON string, you should wrap it in parenthesis (( & )). The parenthesis means it will always be evaluated as an expression, not a block.
Please excuse the awkward title I'll try my best to explain my peculiar problem.
I have three bits of javascript code:
Some self executing code which calls my personal Ajax function and passes it a callback.
The ajax function itself which retrieves the data calls the callback passing it the data.
The callback itself which takes in the data and parses it into an array of n length.
What should be noted is that the self executing code and the callback function are defined within their own closure. The ajax function is accessed through an imported named closure which I defined as $.
I am fairly new to JavaScript and I am still learning about closures and their scopes. I have reason to believe that this problem is probably related to that.
Anyway, my problem relates to trying to access that supposedly populated array. Since I defined the array in a suitable scope (or so I believe) as the parse function I think I should have no problem pushing items into it.
This is self exectuting :
(function ($){
//Load stock
var items = [];
var response = $.Ajax("scripts/Lookup.php","GET",parse);
function parse(a){
for(/*Simplified view*/){
var item = new $.Item();
item.name = domStuff.textContent;
item.description = domStuff.textContent;
item.price = domStuff.textContent;
item.id = domStuff.textContent;
items.push(item);
}
}
//Test the length (and verify contents)
for(var i=0; i < items.length; i++){
alert(items[i].price);
}
}($));
This is my definitions, which includes the Ajax function:
var $ = (function(){
var s = {};
var ajax = function(url,method,callback){
var a = new XMLHttpRequest();
a.open(method, url, true);
a.onreadystatechange = function(){
if(this.readyState==4){
callback(a);
}
}
a.send();
};
s.Ajax = (function(){
return ajax;
}());
return s;
}());
So what justifies the title is that when I probe the code with firebug, I can see that items is populated with 3 Objects correctly defined by the parsed data.
The loop then alerts as intended 3 times.
However, if I remove the break points and have firebug ignore the code then the loop doesn't play out and I can only assume that the array is empty.
The code works also if I alert(items) prior to the test loop.
AJAX is filling items asynchronously, meaning in your closure, on first execution items.length will be zero (from the original array initialization). Over time, AJAX through calls to your parse method will fill this array.
Because you're keeping items in a closure, you won't actually be able to access it from outside - which is a good practice, but can cause problems with debugging! Instead of items.push(item) try alert(item) (any browser, but execution blocking) or console.log(item) (firebug only) to see that you are, indeed, getting the results back from AJAX just not in initial execution.
I'm not a JavaScript expert by any means. However, I have run into situations on other programming languages where debugging has solved an issue.
In those cases, debugging has slowed the code down enough for it to work. Some process A needs asynchronous process B to return an object or do something before executing beyond a certain point. What is most likely happening in these types of scenarios is that the main thread is continuing or not waiting for the object to be populated by the other routine.
I hope that helps.
Your parse function is called asynchronously. You need to wait for the parse function to be called before testing it.
Either test the result in you parse function or have another function as the callback for ajax call. This function calls parse and then test the results.