开发者

Temporarily change a JavaScript global variable

I'm trying to invisibly swap one library for another but only for a given scope. Here's a simplified sketch of the problem. x represents the old 开发者_Go百科preexisting library, y represents the new library and $ is the global I want to affect. The goal is to have withLib successfully change $ from x to y for all the code within it's callback.

You can see with this example, I can affect the code in the outer context but not the inner. I've tried wrapping the callback() in a closure but that didn't quite do it either.

x = "1.0"
y = "2.0"
$ = x;

withLib = function(callback) {
  $ = y
  callback()
  $ = x
}

withLib(function(){
    console.log($, $ == "2.0" ? "outer success" : 'outer fail')
    someCb = function() {
        console.log($, $=="2.0" ? "inner success" : "inner fail")    
    }
})

someCb() 

// results in "outer success" and "inner fail"

I think the answer involves setting up the right kind of closure but I can't see how. Any thoughts?


You could use an anonymous function to create a scope where $ is y:

x = "1.0"
y = "2.0"
$ = x;

(function ($) {

    console.log($, $ == "2.0" ? "outer success" : 'outer fail')
    someCb = function() {
        console.log($, $=="2.0" ? "inner success" : "inner fail")    
    }

}(y));

someCb()

Alternatively, the keyword with is generally to be avoided, but if you're set on it:

with ({'$': y}) {
    console.log($, $ == "2.0" ? "outer success" : 'outer fail')
    someCb = function() {
        console.log($, $=="2.0" ? "inner success" : "inner fail")    
    }
}


At the top of the function (or functions) that use the old library, you could replace the $ reference, but only in the local scope like so:

function doStuff() {
    var $ = x;
    // do stuff with $
}

This will not affect the global values for $, x, and y, but will only work on calls within the scope of doStuff.


Try http://jsfiddle.net/rQ54s/

x = "1.0"
y = "2.0"

withLib = (function(callback, $) {
  callback($)
})

withLib(function($){
  console.log($, $ == "2.0" ? "outer success" : 'outer fail')
  someCb = function() {
    console.log($, $=="2.0" ? "inner success" : "inner fail")    
  }
}, y)

someCb()

Try withLib(..., x) to pass in x as the "$" library.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜