2

Before anyone marks it as duplicate, this post does not actually answer the question but suggests a different way altogether to solve that particular issue.

Mine is a different issue. Please let me explain.

In my case, there are various .js files (plugins) which are being loaded with jquery getscript and stored in variables. Then whenever required they will be executed (more than once)

The code for loading script (this code will only run once at the init of the system for each plugin js file)

var storedFunc;
$.getScript(pathToPluginJSFile, function( data, textStatus, jqxhr ) {
    storedFunc = data;    
});

All the plugins are in this format

(function(){
  //lots of code here
})()

But when I checked the storedFunc variable in console, I found out that it has been stored as String variable. Like this,

"(function(){
      //lots of code here
 })()"

Now to execute this, I used eval, like this (this code can be executed multiple times based on the need)

eval(storedFunc)

Everything is working fine and i am happy with it, but here comes the problem, I read in somewhere that the usage of eval is kind of like a bad thing to do. So now I am afraid that thought everything is working fine, all these negativity of using eval spread on the internet might scare my client away. :(

So, please tell me how I can run that stored function (which has become a string) without using eval.

Or should I use anything else than $.getScript which does not convert a function into a string ?

Or if there is any other way altogether rewriting this plugin functionality?

Please show me the way. I am in need of this solution badly.

Any help will be appreciated.

Thanks in advance.

Community
  • 1
  • 1
TruthSeeker
  • 128
  • 12
  • 1
    `$.getScript()` loads the file *and executes it*. When your callback is invoked, the script has either run or it was attempted and it failed. You can add another callback via `.fail()` on the value returned from `$.getScript()`. – Pointy May 18 '16 at 18:21
  • @Pointy, So, is there any method other than `$.getScript()` which will only load the function but not execute it immediately? Actually it is working it is what the behavior I want. It needs to be run in initialization and also in any future subsequent cases where needs appear due to reset or something like that. – TruthSeeker May 19 '16 at 04:55

1 Answers1

2

Understanding how $.getScript works

Seems there is some confusion on how $.getScript works. If you notice jQuery's documentation on the method, and as @Pointy made mention of in the comments, this is stated:

Load a JavaScript file from the server using a GET HTTP request, then execute it.

Here's an example: Let's pretend the contents of the file being returned is only this:

// Contents of yourExternalFile.js
console.log('Executed!');

Now, when you use $.getScript:

$.getScript(pathToPluginJSFile, function( data, textStatus, jqxhr ) {
    // The script you retrieved has already executed at this point, and you will find "Executed!" in the console.
    console.log('All Done');
});

Console output:

> Executed!
> All Done

The $.getScript method is not meant to be used to return a string of the content of the file. However, while that data is available in the callback, the contents of the file have already been executed. So by taking the string version of the file, and re-executing it with either new Function, or even eval, you are executing it twice on the page (jQuery does it once, and so do you).


Original Post:

Use the Function constructor instead of using eval.

// Your function as a string stored to a variable
var stringFunction = "(function(){console.log('Executed');})()";

// Use the Function constructor to create a new function:
var executableFunction = new Function(stringFunction);

// Now you can execute it
executableFunction(); // logs "Executed"

This snippet from this SO question/answer addresses the difference between eval and new Function.

  • eval() evaluates a string as a JavaScript expression within the current execution scope and can access local variables.

  • new Function() parses the JavaScript code stored in a string into a function object, which can then be called. It cannot access local variables because the code runs in a separate scope.


Additional Information (Based on comments)

Yes, you can just get the string contents of the file and store them to a variable without the contents of the file executing. You can have that function to execute anytime. You just need to use the regular get method using jquery, and set the dataType to text. This way, the script will not execute, and you can execute it as you see fit:

var storedFunction;

$.get({url: pathToPluginJSFile, dataType: 'text'})
    .done(function (data) {
        // Turn the script into a new function and store it
        // The information in the script file has not done anything yet
        storedFunction = new Function(data);
    })
    .fail(function () {
        console.log('Failed :(');
    });

The only thing you will have to watch out for, is making sure that the function was assigned to the storedFunction variable as you are making an api call, and you have to wait for that to finish before attempting to make the function execute.

// Later on, call that function anytime, and as often as you want:
storedFunction(); 
Community
  • 1
  • 1
KevBot
  • 17,900
  • 5
  • 50
  • 68
  • 1
    This is true, but the whole project is probably unnecessary since `$.getScript()` will run the returned JavaScript anyway. – Pointy May 18 '16 at 19:39
  • @Pointy, thanks for the feedback. I've updated my answer to hopefully clarify for the OP what is probably a misunderstanding of how `$.getScript` works. – KevBot May 18 '16 at 21:13
  • @KevBot, So, is there any other method than `$.getScript()` which will only load the function but not execute it immediately? As I told in the question, the code might need to be run multiple times during the lifetime of the system, that's why there needs to be a storing mechanism to prevent reading again from files. – TruthSeeker May 19 '16 at 04:53
  • @KevBot, Thanks for the answer and the links. It was really very illuminating :) – TruthSeeker May 19 '16 at 04:58
  • 1
    @TruthSeeker, I made an update to the question at the end explaining how to get the contents of the script file but without executing, it and storing it for later use. – KevBot May 19 '16 at 05:15
  • @KevBot, Ok, just getting it as txt. I like how you are calling new Function constructor on it immediately before storing it... Wow. Great code. Thanks :) – TruthSeeker May 19 '16 at 05:25