4

假设我有一个包含以下内容的文件“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(test) 并且仍然看到“某些东西”。

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

4

4 回答 4

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

于 2013-01-10T00:04:30.957 回答
1

您可以eval为此目的使用并在本地范围内创建一个具有预期名称的变量:

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

然后,您需要使用该自定义函数而不是ajax 中用于脚本$.globalEval的(代码)。

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

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

于 2013-01-09T23:54:43.163 回答
1

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

于 2013-01-10T00:20:22.487 回答
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');
        };
    }
}
于 2013-10-23T11:23:04.123 回答