在设置局部变量时,真正的wierd JavaScript行为

在设置局部变量时,真正的wierd JavaScript行为,javascript,jquery,variables,scope,global-variables,Javascript,Jquery,Variables,Scope,Global Variables,我一直在努力完善一个问题的答案,但我遇到了一个棘手的问题,我希望有人能帮助我了解原因。我试图做的是在“受保护”函数中禁用AJAX操作,方法是使用局部范围的变量覆盖它们。这需要使用jQuery之类的库,因此我尝试实现逻辑来重新创建$variable,但由于某些原因,我无法像使用其他库一样使用本地版本覆盖全局范围,同时产生了一些非常意外(和有趣)的行为 这是我正在使用的代码: var testFunction = (function(){ // Global to local/lexical

我一直在努力完善一个问题的答案,但我遇到了一个棘手的问题,我希望有人能帮助我了解原因。我试图做的是在“受保护”函数中禁用AJAX操作,方法是使用局部范围的变量覆盖它们。这需要使用jQuery之类的库,因此我尝试实现逻辑来重新创建$variable,但由于某些原因,我无法像使用其他库一样使用本地版本覆盖全局范围,同时产生了一些非常意外(和有趣)的行为

这是我正在使用的代码:

var testFunction = (function(){
    // Global to local/lexical:
    var XMLHttpRequest = undefined;
    var eval = undefined;
    var setTimeout = undefined;
    var setInterval = undefined;
    var Function = undefined;
    var window = undefined;
    // Can't set directly to var $?
    var $new = (function($old){ if($old) {
        var newjq = function(s, c) {
            // Reroute main function
            return $old(s, c);
            };
        var jQueryBlacklist = {
            // Initialize blacklist
            "ajax": true,
            "post": true,
            "get": true,
            "getJSON": true,
            "getScript": true
            };
        for(i in $old) // Reconstruct Object
         if($old.hasOwnProperty(i)
         && !jQueryBlacklist[i])
          newjq[i] = $old[i];
        return newjq;
        } }($));
    // Line below completely breaks script?:
    var $ = $new;
    if(!$new) alert("$new is undefined");
    // Real testFunction() below:
    return function() {
        // AJAX-forbidden code
        if(!$) alert("$ is undefined");
        else alert("jQuery is working");
        // alert($.ajax);
        // $.ajax should be undefined
        }
    }());
testFunction();
// alert($.ajax);
// should be defined
你可以点击查看小提琴


我只是对这方面的任何反馈感兴趣,对我来说,这似乎是一个bug。我想知道这种行为的原因。提前谢谢

您的
var$
被提升(声明被移动到函数顶部),将全局
$
隐藏为未定义(当它被传递到自执行函数中时),直到它在
var$=new$
中的实际赋值

最简单的解决方案是将jquery传递到您的模块中

var testFunction=(函数($){
//全局到局部/词汇:
var XMLHttpRequest=未定义;
var eval=未定义;
var setTimeout=未定义;
var setInterval=未定义;
var函数=未定义;
var窗口=未定义;
//无法直接设置为var$?
var$new=(函数($old){
如果(旧){
var newjq=函数(s,c){
//重路由主功能
返回$old(s,c);
};
var jQueryBlacklist={
//初始化黑名单
“ajax”:没错,
“post”:没错,
“得到”:真的,
“getJSON”:true,
“getScript”:true
};
for(i在$old中)//重构对象
if($old.hasOwnProperty(i)&&!jQueryBlacklist[i])newjq[i]=$old[i];
返回newjq;
}
}($));
//下面的行仅影响传递到此模块的对象引用
//不影响此函数之外的jQuery:
$=$新;
如果(!$new)警报($new未定义);
//下面是Real testFunction():
返回函数(){
//AJAX禁止代码
如果(!$)警报($未定义);
else警报(“jQuery正在工作”);
//警报($.ajax);
//$.ajax应该是未定义的
}
}(jQuery));
testFunction()

脚本这一部分的全部要点是在本地范围内重写$,因此重命名不会解决问题。是什么原因导致美元被提升到顶部?有什么方法可以防止这种情况发生吗?另外,我不能忽略“var”声明,因为这会覆盖全局变量。我只是想推翻它。你有没有别的解决办法?我现在没有主意了。Lol@JonathanGray提升就是JavaScript的工作方式。可以将对jQuery的引用传递到函数中。查看更新后的Answerah,我完全忘记了将变量作为参数传递,以替代“var”声明。非常好的解决方法:)