Chrome JavaScript调试:如何在值改变时中断

17

我正在调试一个大型JavaScript代码库,在某些情况下,当刷新页面时,“console”变量会被清空。

有没有办法在控制台上设置监视器并在该值改变时(或条件(console == null)为真时)使JavaScript中断执行?

我使用的是Windows 7上的Chrome浏览器。


类似的问题可以在这里找到:http://stackoverflow.com/questions/12577535/break-points-on-user-defined-object-properties-in-javascript - Jineesh
解决方案在这里:https://stackoverflow.com/questions/56582385/devtools-break-on-expression/56582386#56582386 - Vic Seedoubleyew
3个回答

22
下面的答案对于window.console无效,因为像其他浏览器本地环境变量一样,console被特殊处理。任何尝试将值分配给console的操作都只会“覆盖”原始值,而不是替换它。您无法检测console值的更改,但您可以使用delete window.console来恢复原始的环境提供的值。 对于其他值,请使用Object.defineProperty为某些全局window.foobar定义一个自定义setter。当分配新值给window.foobar时,setter函数运行:
(function() {
    var actualFoobar = window.foobar;

    Object.defineProperty(window, "foobar", {
        set: function(newValue) {
            if(newValue === null) { 
                alert("someone is clobbering foobar!"); // <-- breakpoint here!
            }

            // comment out to disallow setting window.foobar
            actualFoobar = newValue;
        },

        get: function() { return actualFoobar; }
    });

})();

然后,在该setter函数中设置断点。

这种方法适用于全局变量或任何对象属性(只需将window更改为具有该属性的对象即可)。


2
也许更加详细的做法是使用 console.trace() 来进行警告、记录或输出日志。 - Elias Van Ootegem
@EliasVanOotegem 一个很好的建议,我已经添加了。虽然原帖只是想添加断点,但这仍然是一个不错的想法。 - apsillers
我还没有在实际脚本中测试过你的建议,但是当我将其粘贴到浏览器控制台中时,除非整个控制台被重新分配,否则它根本没有任何区别。当重新分配 console.log 时,它仍然会出错。 - Elias Van Ootegem
没错,这就是意图,不是吗?来自OP的话:“在刷新页面时,某个时刻,“console”变量被置为空。” OP说他想要监视“console”变量,而不是它的任何成员变量,因此“console.log”应该是可以自由置空的。我是否误读了问题?或者你的意思是我的代码会导致“console.log”无法再次置空? - apsillers
确实是 console,而不是 console.log 被覆盖了。感谢您的代码,在通常情况下这是捕获全局变量更改的好方法。神奇的是,在我的情况下它并没有被触发,但是其纯粹的存在(get 方法返回 actualConsole)解决了问题。 - Janik Zikovsky

0

浏览器中的函数无法设置为空!从技术角度来说。

如果window.console.log函数被赋值为null,只需删除它然后恢复原样!

delete console.log

这样就可以完成任务了 :)

编辑:这不是你主要问题的答案,但我认为你的问题来自于你正在寻找一种调试的方法,因此这个答案基本上跳过了检测变量更改的需要。


“console”不是一个函数,而是一个对象,它可以被设置为null。 - Madbreaks

0

你不能触碰console对象... 永远不行。唯一可能发生的事情是在作用域/命名空间中声明了一个console变量,而不是全局作用域,从而隐藏了全局控制台。但你仍然可以使用window.console访问它。除此之外,我能想到的唯一可能原因是:

  • 你已经在控制台覆盖中设置了用户代理,以模拟不支持console的IE版本
  • 你的代码由于其他问题而抛出错误
  • 正如@alexandernst所指出的那样:你正在覆盖控制台对象的属性。删除你无法访问的方法,问题就解决了

要找出需要查看代码的位置,设置条件断点并观察一些表达式,使用暂停未捕获的异常按钮


我发现覆盖console会导致其失效。window.console不能回到原始的控制台。 - Janik Zikovsky
如果console在全局作用域以外的范围被重新定义,那么使用window.console将起作用。如果window.console不起作用,那么很有可能delete console;或者delete window.console可以解决问题。 - Elias Van Ootegem
这个答案非常旧,我知道,但是它没有意义。只需尝试在开发工具中打开您的控制台并键入:'window.console = null'。游戏结束。 - Madbreaks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接