使用jQuery加载脚本时保持范围

时间:2013-01-09 23:43:50

标签: javascript jquery ajax scope

说我有一个'test.js'文件,其中包含以下内容:

var test = 'something';

然后我有一个主脚本,需要加载test.js来获取测试变量。

显然这有效:

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

问题是变量test存在于全局范围内。我很好奇是否有办法将其添加到对象中并使其远离全局范围。

类似的东西:

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

var myloader = new scriptloader();

myloader.grabscript();

理想情况下,myloader将包含加载的变量test。但是,我可以使用console.log(测试)并仍然看到'某事'。

有没有办法将加载的脚本锁定到范围内还是我在做梦?

4 个答案:

答案 0 :(得分:3)

您可以尝试这样的事情:

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'
    });
  }
}

scriptloader实例将获得名为test的属性。

答案 1 :(得分:1)

您可以将eval用于此目的,并在本地范围内创建具有预期名称的变量:

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

然后,您需要使用$.globalEval中使用的自定义函数,而不是codeajax for scripts)。

当然,对于每个全局变量来说,这不是一个包罗万象的方法,因为您需要创建一个单独的全局对象(例如使用<iframe>)来评估那里的脚本。

但是,使用JSONP可能比使用变量更好。

答案 2 :(得分:1)

如果您无法控制test.js,并且必须接受将该测试声明为全局变量,则解决方法是在页面中的iframe中加载test.js.这种方式测试将是一个全局变量,但仅在iframe窗口的范围内。在您的主页上,您将能够以ifr.contentWindow.test

的形式访问它

答案 3 :(得分:0)

您可以尝试扩展页面上已存在的对象。

假设您的网页上有这样的脚本

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']();
});

您的test.js文件:

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

        app.someVar = 1;

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