Is it possible to extract functions from a javascript file?

Not sure if this is the right approach if this is even a "good" question, but I am loading javscript as part of the plugin style architecture and I have the following problem:

If a specific node has a link to a plugin, I want to load that plugin to the url provided via the json description of that plugin. the description will have something like the following (or functional equivalent):

{
  "pluginSrc" : "http://mysite.com/plugins/1204.js",
  "configData" :
    {
      "someData", "someValue",
      "someMoreData", "etc"
    }
}

      

When the javascript is loaded, I will have an onload handler that checks if the object name exists in the window object, and if so, create a new instance of that function and pass the config data to it (more or less)), this part works very well, behind some exceptions.

Sometimes I don't have a reference to the name of the function I need to call and there is no way to get it from json. Which would be ideal if I could determine which function was added to the window object in the script callback and instantiate that function. Is it possible? I only need to worry about modern browsers, especially webkit. I apologize if the question is not clear, I would be happy to clarify, but creating a fiddle can be tricky as there is a lot of code to write to achieve a minimal example.

What I am currently thinking about is creating some kind of global variable in the loaded script file like

function MediaAnalytics(){};
var LoadedClass = MediaAnalytics;

      

and just creating an instance of LoadedClass when the script is loaded, but this is not a panacea, because I won't always write a plugin.

EDIT: These scripts most likely won't be from the same domain.

+3


source to share


2 answers


You have not specified how you load the script file. I hope you get the script text in your onload handler.

Anyway, I am explaining how to do it using jQuery.getScript

. In this case, you will get the script text in your success handler as data

. So you can use that to get the loaded function.

Suppose your script file dynamic.js contains

function MediaAnalytics(){};

      

load it with getScript

$.getScript("dynamic.js", function (data, textStatus, jqxhr) {
    var NewFunction;
    eval("NewFunction = " + data);
    alert(NewFunction.name); // here you will get alert showing MediaAnalytics
});

      

There NewFunction

is MediaAnalytics

. This will be the second execution of the script as it getScript

calls the success handler after it has completed and adds it to the window object. You can give new NewFunction()

to instantiate.



If you don't prefer to use eval

, another way is to use RegEx to look up the function name

$.getScript("dynamic.js", function (data, textStatus, jqxhr) {
    alert(data.match(/function(.*)\(/)); 
});

      

This will trigger the MediaAnalytics ( . match

) Function returns an array. The function name can be extracted from it.

You can use a better RegExp to extract the exact function name and get the property of the window object.

EDIT: (no jquery)

Or you can load script text as text and add to window as script tag in onload handler. There you can use your trick even if the script plugin is not yours.

var dynamicjs = "function MediaAnalytics(){};";  // script loaded as text

var modified = "LoadedClass = " + dynamicjs;

var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.textContent= modified;  // innerText in some browsers
head.appendChild(script);

alert(LoadedClass);  // LoadedClass is MediaAnalytics

      

+2


source


I would suggest doing this to have the login function name in json. This would be the least dangerous way to do it in my opinion.

However, you could try to iterate over all properties window

. If you find a new function in the window

after loading script, you can assume that the one that just loaded.

Something like that..



var windowMembers = [];
function loadScript() {
    for(var m in window) {
        windowMembers.push(m);
    }

    //load your new script
    //some code here to load the script

    //put an onload handler...
    s.onload = function() {
        for(var m in window) {
            if(windowMembers.indexOf(m) == -1) {
                //window[m] was added after the script loading began
                //call it:
                window[m]('blah blah');
            }
        }
    }
}

      

To be on the safe side, you could additionally check if the new property is a function, eg.

if(typeof window[m] == 'function')

      

+1


source







All Articles