Maintain scope when loading script with jQuery

删除回忆录丶 提交于 2019-12-10 16:22:22

问题


Say I have a file 'test.js' with the following contents:

var test = 'something';

Then I have a primary script that needs to load up test.js to grab the test variable.

Obviously this works:

$.ajax({dataType: "script", cache: true, url: 'test.js'});

The issue is that the variable test exists in the global scope. I'm curious if there's a way to add it into an object and keep it out of the global scope.

Something like:

function scriptloader() {
    this.grabscript = function() {
        return $.ajax({dataType: "script", cache: true, url: 'test.js'});
    }
}

var myloader = new scriptloader();

myloader.grabscript();

Where ideally myloader would contain the loaded variable test. However, I can console.log(test) and still see 'something'.

Is there a way to lock the loaded script into scope or am I dreaming?


回答1:


You could try something like this:

function scriptloader() {
  this.grabscript = function() {
    var loader = this;
    $.ajax('test.js', {
      complete: function(response) {
        var js = '(function() {' + response.responseText + ' loader.test = test; })();'
        eval(js);
      },
      dataType: 'text'
    });
  }
}

The scriptloader instance would then get a property called test.




回答2:


You could use eval for that purpose and create a variable with the expected name in the local scope:

(function(jsString) {
    var test;
    eval(jsString);
    console.log(test); // 'something'
})("var test = 'something';");
console.log(test); // Exception: undefined variable

You then need to use that custom function instead of $.globalEval (code) as used in ajax for scripts.

Of course this is not a catch-all method for every global variable, for something like that you would need to create a separate global object (e.g. with an <iframe>) to evalute the script there.

However, using JSONP might be a better idea than using variables.




回答3:


If you have no control over test.js, and must accept that test is declared as a global variable, a workaround would be to load test.js in an iframe within your page. This way test will be a global variable but only within the scope of the iframe window. From your main page, you'll be able to access it as ifr.contentWindow.test.




回答4:


you could try to extend an object that already exists on your page.

Say you have a script on your page like this

var app = {
    loadedScripts
    ,loadPageScript : function(scriptUrl, cb) {
        $.getScript(scriptUrl, cb)
            .fail(function( jqxhr, settings, exception ) {
                console.log(exception);
        })
    }
}

app.loadPageScript('/test.js', function(){
    app.loadedScripts['test']();
});

Your test.js file:

if(!app.loadedScripts.test){
    app.loadedScripts.test = function() {

        app.someVar = 1;

        app.someFunction = function(){
            console.log('iha');
        };
    }
}


来源:https://stackoverflow.com/questions/14248491/maintain-scope-when-loading-script-with-jquery

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!