设置局部变量时,真的很奇怪的JavaScript行为

时间:2014-11-19 18:40:06

标签: javascript jquery variables scope global-variables

我一直试图在这里提出一个问题的答案,但我遇到了一个奇怪的问题,我希望有人可以帮我理解原因。我试图做的是通过用本地范围的变量覆盖它们来禁用在“受保护”函数中使用AJAX操作。这需要与jQuery这样的库一起工作,所以我尝试实现逻辑来重新创建$变量但由于某种原因我不能用本地版本覆盖全局范围,就像我可以与其他版本一样,同时产生一些非常意外的(和有趣的)行为。

这是我正在使用的代码:

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

您可以点击here查看小提琴。

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

1 个答案:

答案 0 :(得分:2)

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

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



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 only affects the object reference passed in to this module
    // Doesn't affect jQuery outside of this function:
    $ = $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
    }
}(jQuery));
testFunction();

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;