最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Maintain scope when loading script with jQuery - Stack Overflow

programmeradmin1浏览0评论

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?

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?

Share Improve this question asked Jan 9, 2013 at 23:43 FluidbyteFluidbyte 5,21010 gold badges49 silver badges80 bronze badges 5
  • 1 Interesting question... the only way I could think of isolating the loaded file in it's own context would be to load the file via an iframe, then extract the object from the parent – Justin Bicknell Commented Jan 9, 2013 at 23:51
  • That's actually an interesting idea... – Fluidbyte Commented Jan 9, 2013 at 23:53
  • 1 Couldn't one argue that if such a scenario is occuring then perhaps you should rethink your design approach as far as the placement of var test = 'something'; is concerned??? Seems like there is a better place for it than in your test.js script since it is needed elsewhere. – Matthew Cox Commented Jan 10, 2013 at 0:10
  • Do you have control over test.js? – Christophe Commented Jan 10, 2013 at 0:12
  • That's obviously a simple example. In reality it's loading in a script that acts as a model for a data set so my problem is I can't restructure it (i.e. contain it in an object). – Fluidbyte Commented Jan 10, 2013 at 0:18
Add a ment  | 

4 Answers 4

Reset to default 3

You could try something like this:

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

The scriptloader instance would then get a property called test.

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.

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.

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');
        };
    }
}
发布评论

评论列表(0)

  1. 暂无评论