【问题标题】:Why getting "Uncaught ReferenceError: $ is not defined" error on Chrome Dev Console?为什么在 Chrome 开发控制台上出现“未捕获的 ReferenceError:$ 未定义”错误?
【发布时间】:2018-08-02 17:16:04
【问题描述】:

我正在尝试在 Chrome 开发者控制台中运行一个简单的 JQuery 脚本,但我遇到了问题。

我在 Chrome 开发者控制台上运行这段代码没有问题:

var someValue = $("[name='Jack']");
if(someValue !== null){
   console.log("Jack is here!");
}

但是,当我尝试在 setTimeout 函数中运行相同的代码时出现错误,如下所示:

setTimeout(function(){
   var someValue = $("[name='Jack']");
   if(someValue !== null){
      console.log("Jack is here!");
   }
}, 1000);

未捕获的引用错误:$ 未定义

这不仅发生在 setTimeout 函数中,它也发生在普通函数中。

我正在使用最新版本的 Google Chrome。如何在 setTimeout 函数中使用上述 JQuery?

【问题讨论】:

  • 您是从控制台还是从脚本文件运行 setTimeout() 函数?如果来自脚本文件,您可能会在加载 JQuery 文件之前使用 setTimeout() 加载脚本。
  • 不,我只是在使用 Chrome 控制台。没有任何脚本文件。
  • 首先在你的控制台中运行这个:var script = document.createElement('script');script.src = "https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js";document.getElementsByTagName('head')[0].appendChild(script); 你正在工作的页面可能不会在你的代码之前加载jquery
  • 感谢@EmmanuelNK 成功了。我想知道为什么它在函数之外起作用而不在内部起作用?
  • @Lujska 因为$ 是控制台内置的,但在setTimeout 等其他上下文中却不是。

标签: javascript jquery google-chrome google-chrome-devtools


【解决方案1】:

问题是因为 Jquery 库在您的自定义代码加载后加载。

您是否为自定义脚本使用外部 js 文件? 然后你在 jquery 脚本下加载你的脚本。

您必须先添加 jquery 库链接,然后再添加您的脚本。

【讨论】:

    【解决方案2】:

    这里的混淆集中在$Chrome's Command Line API 的一部分这一事实上。当您在代码中使用$ 时,您指的是名为$ 的命令行API 函数。您可能根本没有加载 jQuery:事实上,您的 someValue !== null 代码甚至无法与 jQuery 一起使用。您需要测试非空 jQuery 对象 (someValue.length > 0),而不是非null

    至于 为什么 Chrome 的 $ 可以在控制台中访问,但不能在 setTimeout 回调中访问:这似乎是特定于引擎的魔法,它将命令行 API 仅限于控制台代码。 setTimeout 以 Chrome 无法确定代码来自控制台的方式执行其回调,因此它不会授予对名为 $ 的命令行 API 函数的访问权限。奇怪的是,这不是 JavaScript 的典型特征。使用普通的 JavaScript 范围规则,setTimeout 回调 应该 可以访问与周围代码相同的变量,无论何时何地执行。一秒钟后范围不同的事实非常令人惊讶-您感到困惑是对的!


    出于好奇,在 vanilla JavaScript 中模拟这种情况的一种方法是通过with 使用基于对象的范围,该范围在命令完成后会发生变化。例如,如果您在控制台中输入的每个 sn-p 都被包装了:

    var chromeConsoleAPI = { $: function() { ... } }
    with(chromeConsoleAPI) {
        // your snippet here
    }
    delete chromeConsoleAPI.$;
    

    在这种情况下,$ 是通过访问作用域链上的 chromeConsoleAPI 对象来提供的。普通代码可以访问$,但由于setTimeout函数在chromeConsoleAPI.$被删除后运行,所以它找不到任何名为$的东西。请注意,这仍然不能完全复制行为,因为这会阻止对任何用户定义的$ 的访问。实际上,命令行 API 必须将其函数注入作用域链的最顶端(即最远程)部分。

    【讨论】:

    • 在 Chrome 68 中仍然如此吗? setTimeout(() => console.log($("body")), 0) 在控制台中对我来说很好用。顺便说一句,您提到with 让我意识到我可以使用它来使命令行copy() 函数在回调中可用:stackoverflow.com/a/51912170/4200446
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2021-04-24
    • 1970-01-01
    相关资源
    最近更新 更多