Reputation: 5210
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?
Upvotes: 4
Views: 3459
Reputation:
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');
};
}
}
Upvotes: 0
Reputation: 6515
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
.
Upvotes: 3
Reputation: 28154
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
.
Upvotes: 1
Reputation: 664650
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.
Upvotes: 1