Execute JavaScript from String - javascript

So, I want to run this script when button A is clicked. The script is stored in an Object as a string. When button A is clicked, I use eval, like: eval(Object[script]). This works fine, unless I have functions within the script, when I do, it breaks because they are not getting defined. Is there a way to get around this? I tried putting the function definition in a var and putting it at the top of the script. Now, if I simply copy my script to the console, it executes perfectly. Is there a way to execute a script as if it were typed into the console?
FYI: This is a simplification of my problem, I realize there are better ways to do what I describe here.

The best fix is to stop storing code as strings. Use functions instead.
buttonA.script = function() {
do whatever you were doing in your eval
};
// then, instead of `eval(buttonA['script'])`, say...
buttonA.script();
// or, if the name is in a variable...
var foo = 'script'; // for example
buttonA[foo]();
About the only time eval makes sense is when you have code that by its very nature has to be dynamically generated or interpreted. For the vast majority of cases, that is not true. I can only think of a case where it would be true, in fact: the textarea script testing thing mentioned in the comments.
For every other case...
obj = {
first: function() {
function test() { alert('hi'); }
test();
}
};
obj['first']();
// or simply
obj.first();
// and what's more...`test` doesn't escape and trample on stuff.
try { test(); }
catch (ex) { alert("" + ex); } says `test` is not defined

This works:
var oFunc = function (value) {
alert(value)
}
var obj = { code: "oFunc('hello')" }
eval(obj["code"]);
Or am I missing something?
Update
This also works
var obj = { code: "var oFunc = function (value) {alert(value)}; oFunc('hello')" }
eval(obj["code"]);

In your code alert(hi) should be alert("hi")
obj = {
first: 'function test() { alert("hi") } test();'
}
eval(obj["first"]);
DEMO.

Related

How to use only parenthesis without the function in javascript?

The question may not be clear, so I will clear that here. I am using require.js to import a script in script. Here is a piece of code :
var vr = {};
vr.example = function(func) {
return require(["https://example.com"], func);
};
So, now I am able to call it by :
vr.example( function() { .... });
But, I am thinking about not writing the function everytime I have to call it. I would like to write something like this :
vr.example({ ... });
And the result should be same. But I can't understand how to do it. So please help
Thanks in advance.
The thing you want can't be done in JavaScript ! But there is a way to do, by making an interpreter. Here is a basic example. I don't really recommend it, well I am showing you just a possibility ;)
window.InterpretData = function() {
var el = document.querySelectorAll("script[type='text/test']") // You can change it anyway !
for(var i = 0; i < el.length; ++i) { // You can use i++ instead of ++i, but ++i is much optimised for this function, watch out their differences in the internet.
var val = el[i].innerHTML
var crt = document.createElement("script")
crt.id = "InterpretedScript"
document.getElementsByTagName("body")[0].appendChild(crt) // Creating a new script element
val = val.replace(/\.example\(\{([\S\s]*?)\}\)/gm, function(_, a) { // Wish you are familiar with regular expressions
a = ".example( function() {" + a + "})"
document.getElementById("InterpretedScript").innerHTML += a;
}
}
}
Now you can do :
<!DOCTYPE html>
<body>
<script type="text/test">
// Defining
var vr = {};
vr.example = function(func) {
return require(["https://example.com"], func);
};
// Calling
var.example({ ... })
<script>
<script>
new InterpretData()
</script>
</body>
</html>
Output :
vr.example({ ... }) converts to vr.example( function() { ... })
Well, remember this example is just to give you an idea about a possibility to solve your problem. It's not the perfect solution though you can't again declare the "example()" to any other constant / variables, that contain different parameters ! So, the only way lies to either use ES6's fat arrows (=>) or just declare the function earlier and go on reusing it ! If you have to support old browsers than go with reusing technique shown by #mbojko, or just go with ES6's fat arrows, said earlier by #deceze. So, want do you think ?
So, you want to pass a block of code not wrapped with a function? Short answer: you can't do that in JavaScript. And require.js does expect a callback function at any rate.
If the callback function is reusable, you can declare it once and reuse it like:
function myReusableCallback(args) {
//...
}
vr.example(myReusableCallback);
And that's pretty much it.
Because the require() function returned from the vr.example() takes a callback function and since this callback function is usually provided by the invocation of vr.example, it, therefore, means you can't necessarily call it with and object as you want to. So you can only use an object if there is no callback expected by the require() an or if you have a static function that you want to be executed all the time then you can implement the function inside of the vr.example and then just pass the object which you need to use inside the function.
It's not possible because {} is not a function, it's an object.
You can try it out yourself using typeof({}) and compare it to typeof(() => {}) or typeof(function() {})

Pass javascript variable to a javascript on a different website

Is it possible to pass a javascript-variable to a script on another site?
I would like to do something like this:
This code is in a page on www.myfirstsite.net:
<script>
var ID = 'randomstring';
</script>
<script src="http://www.mysecondesite.net/processingscript.js"></script>
How can I read the var ID in the script on mysecondsite.net?
Update:
My question is wrong, as explained in the helpful answers from #vihan1086 and others.
Why to never do that
You should never declare variables like that, it has been described here
Then What?
On one page, do:
window.globals = {};
window.globals.my_variable = 'ABC';
On the script, add:
var globals = window.globals;
globals.my_variable;//Gets 'ABC'
This will keep all variables safe in a global place. Then we can get all global variables at once, increasing speed.
Don't forget to wrap all your code in something like:
(function() {
//Code here
})();
Functions
To make this easier I made functions:
setSharedVar (name, value) {
if (!"globals" in window) {
window.globals = {};
}
window.globals[name] = value;
}
getSharedVar (name) {
if (!"globals" in window) {
window.globals = {};
return null;
} else if (!name in window.globals) {
return null;
} else {
return window.globals[name];
}
}
Examples
Script 1:
setSharedVar('id', 5);
Script 2:
if (getSharedVar('id') === 5) {
alert('Success!');
}
Alerts 'Success!'
In your other script, ID will already exist and you can just use it.
Javascript runs in an environment attached to you web page, so as long a you dont change pages you can setup variable and includes other scripts that will have access to them.
So what you are proposing should work
However you should know that running script from other websites can be seen as dangerous and is therefore forbiden by some navigators/plugins ... so you should try and avoid it if possible (by providing a copy of the script on your website)

return statement in JavaScript illegal

I am making this function in java script and keep geting the synatx error don know why please help since i am new to java script. I don knw wat is wrong. Below is the code.
function create(sourceCanvas) {
var JSARRaster = new NyARRgbRaster_Canvas2D(sourceCanvas);
var JSARParameters = new FLARParam(sourceCanvas.width, sourceCanvas.height);
var JSARDetector = new FLARMultiIdMarkerDetector(JSARParameters, 120);
JSARDetector.setContinueMode(true);
return {
"create": create(),
}
This code is unintelligible. I don't think it's a syntax problem, so much as a complete lack of understanding of how functions work. You are using objects and a function, and it seems like you don't really understand either. I'm not saying this to be rude, just stating my perception of your question. In fact, I'll try to break it down for you.
function create(sourceCanvas) {
This is the function definition. It means that when you use the keyword "create" the computer should link to the block of code in between the curly braces {}. You have an opening curly brace, but no closing one, so that is a syntax error. In the create function definition you have listed "sourceCanvas" as an argument. That means that you are telling the computer that you need that variable to execute the code in the body of the function.
var JSARRaster = new NyARRgbRaster_Canvas2D(sourceCanvas);
var JSARParameters = new FLARParam(sourceCanvas.width, sourceCanvas.height);
var JSARDetector = new FLARMultiIdMarkerDetector(JSARParameters, 120);
JSARDetector.setContinueMode(true);
return {
"create": create(),
}
Here you are calling the "create" function. But you don't have any arguments listed. Remember how you need a "sourceCanvas" argument? That will cause another syntax error. Also you are calling the "create" function inside the "create" function. That will cause an infinite loop that will crash your machine.
{ "create": create(), } is an object. It has an attribute "create" and the value of "create" is whatever the function create() returns. Since there is only one attribute, you don't need the comma. That's another syntax error.
I don't know what your function is supposed to do, but here is a version that will compile:
function create(sourceCanvas) {
var JSARRaster = new NyARRgbRaster_Canvas2D(sourceCanvas);
var JSARParameters = new FLARParam(sourceCanvas.width, sourceCanvas.height);
var JSARDetector = new FLARMultiIdMarkerDetector(JSARParameters, 120);
JSARDetector.setContinueMode(true);
return {
JSARRaster: JSARRaster,
JSARParameters: JSARParameters,
JSARDetector: JSARDetector
}
}
According to your code here:
object [object Object] is not a function in javascript
Your code is laid out like this:
function create() {
return {
detect: detect,
getCameraMatrix: getCameraMatrix,
}
}
return { create: create };
So that bottom "return" is outside the create function.
Return has to be in a function.

Object property initially returns undefined, but upon redefinition returns expected value

I’ve got a JavaScript object built like this:
var Dashboard = {
form: {
action: function(){
return $('#upload_form').attr('action');
}(),
//snip (more functions)
}
}
If I call (using Chrome 17 on WinXP) Dashboard.form.action in the Chrome console after the page loaded (I checked the script and the function is there) the result is undefined but, if I then redefine Dashboard.form.action using the same function:
Dashboard.form.action = function(){
return $('#upload_form').attr('action');
}();
and subsequently call it, it works as expected!
What am I doing wrong? Is this a bug or am I just overthinking it?
Update:
Re your comment below:
actually what I want to do IS assigning the result to the action property...
In the question you said:
If I call...Dashboard.form.action...
which makes it seem like you're expecting action to be a function (you don't "call" non-functions).
If you're expecting it to be a string (the "action" attribute value from #upload_form), then you don't need to use a function at all. But you do need to be sure that you're doing it after the #upload_form element already exists in the DOM.
To do that, either put your script below it in the markup (anywhere below it is fine; just before or just after the closing </body> tag works well), or wrap your script in a ready call.
So your code becomes either this if it's after the #upload_form in the markup:
var Dashboard = {
form : {
action : $('#upload_form').attr('action'),
//snip (more functions)
}
};
...or this if you want to use ready (anything else using Dashboard will have to wait until ready as well):
jQuery(function($) {
var Dashboard = {
form : {
action : $('#upload_form').attr('action'),
//snip (more functions)
}
};
});
Note that in the second case, Dashboard will no longer be a global variable. That's a good thing, but if you need it to be global for some reason, you can export it:
jQuery(function($) {
var Dashboard = {
form : {
action : $('#upload_form').attr('action'),
//snip (more functions)
}
};
// Export the global
window.Dashboard = Dashboard;
});
Just make sure nothing tries to use Dashboard before ready has fired.
Original answer:
You have an extra pair of () on that:
action: function(){return $('#upload_form').attr('action');}()
// here -------^^
By putting them there, you call the function immediately, and assign the result of calling it to the action property. You just want to assign the function itself to the property, so don't put the () at the end to call it:
action: function(){return $('#upload_form').attr('action');}
This is for exactly the same reason you wouldn't use () here (let's assume you have a function called foo) if you want f to refer to foo:
var f = foo;
If you said
var f = foo();
...you'd be calling foo, not referring to it.

Calling the function immediately on the call of the page

var ObjectLiteral = {
myName:function() {
}
}
I want to call the myName function immeditetly when the page is
loaded.
I am not sure hot to write a self calling function inside an
ObjectLiteral...
You can't assign a function while simultaneously calling it (since calling it means that its return value gets assigned instead). You have to do this in two steps.
var ObjectLiteral = {
myName:function() {
}
};
ObjectLiteral.myName();
Just because no one mentioned it:
var ObjectLiteral = {
myName: function() {
console.log('myName was called!');
return arguments.callee;
}()
}
Since arguments.callee is deprecated in ES5, we would need to give the method a name:
var ObjectLiteral = {
myName: function _myName() {
console.log('myName was called!');
return _myName;
}()
}
Done. The method would get called at pageload and would still be callable later on. The caveat of doing it that way is the this context value which is replaced with window or undefined (strict) on the self-executing method. But you could apply some magic to solve that aswell. For instance, invoking .call(ObjectLiteral) in es3 or .bind(ObjectLiteral) in es5.
var ObjectLiteral = {
myName: function _myName() {
console.log('myName was called!');
return _myName;
}.call(ObjectLiteral)
}
Looks like I was wrong (damn!). The idea ok, but the assignment to ObjectLiteral is not done on the first invocation of myName. Therefore, the above code will only run from the second call on, which of course makes it useless anyway. You would need to invoke another context, but that would be just overkill.
It still does work after all, but it screws up if you need to access this, otherwise its a fine solution I think.
For your first question:
The simplest possible answer is to add this line to your script:
window.onload = ObjectLiteral.myName();
A better answer is to include that line somewhere in a larger function assigned to window.onload:
window.onload = function () {
....
ObjectLiteral.myName();
}
An even better answer is to scope things properly in case window has been reassigned.
For the second question, what to you mean by self-calling? (EDIT: n/m, Quentin answered)
Taking into account you want to execute your code after page load, jQuery is very suitable for that:
$(function() {
// called then page loaded..
var ObjectLiteral = {
myName:function() {
}
};
ObjectLiteral.myName();
});

Categories

Resources