【问题标题】:Really wierd JavaScript behaviour while setting local variables设置局部变量时非常奇怪的 JavaScript 行为
【发布时间】:2015-01-17 10:05:33
【问题描述】:

我一直在尝试完善关于 SO 的问题的答案,但我遇到了一个奇怪的问题,我希望有人可以帮助我理解原因。我试图做的是通过用局部范围的变量覆盖它们来禁用“受保护”函数中的 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查看小提琴。

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

【问题讨论】:

    标签: javascript jquery variables scope global-variables


    【解决方案1】:

    你的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>

    【讨论】:

    • 这部分脚本的重点是在本地范围内覆盖 $,因此重命名不会解决问题。是什么导致 $ 被提升到顶部?有什么办法可以防止这种情况发生吗?
    • 另外,我不能省略“var”声明,因为它会覆盖全局变量。我只想覆盖它。您可能会想到其他解决方案吗?我现在完全没有想法。大声笑
    • @JonathanGray 提升正是 JavaScript 的工作原理。您可以将 jQuery 的引用传递给您的函数。查看更新的答案
    • 啊,我完全忘记了将变量作为参数传递以替代“var”声明。非常好的解决方法:)
    猜你喜欢
    • 1970-01-01
    • 2018-09-01
    • 2013-01-16
    • 2016-08-24
    • 2023-03-08
    • 2016-03-13
    • 2011-03-01
    • 1970-01-01
    • 2018-02-19
    相关资源
    最近更新 更多