在调试模式下定义的函数立即消失

问题描述

在断点期间,我在控制台中定义了一个函数(如 here 所述),但我无法在控制台中使用它(“未定义”错误)。

为什么我刚刚定义的函数会立即消失?我该如何使用它?

解决方法

为什么我刚刚定义的函数会立即消失?

也许开发人员不希望函数可以被定义并可能在断点处立即执行(不确定)。

我该如何使用它?

方法一:先加载页面,再运行代码片段。

方法二:如果想在断点激活时成功定义函数breakOn,将它定义为变量(由'root'指出)

var breakOn = function (obj,propertyName,mode,func) {
    // this is directly from https://github.com/paulmillr/es6-shim
    var getPropertyDescriptor = function (obj,name) {
        var property = Object.getOwnPropertyDescriptor(obj,name);
        var proto = Object.getPrototypeOf(obj);
        while (property === undefined && proto !== null) {
            property = Object.getOwnPropertyDescriptor(proto,name);
            proto = Object.getPrototypeOf(proto);
        }
        return property;
    }

    var verifyNotWritable = function() {
        if (mode !== 'read')
            throw "This property is not writable,so only possible mode is 'read'.";
    }

    var enabled = true;
    var originalProperty = getPropertyDescriptor(obj,propertyName);
    var newProperty = { enumerable: originalProperty.enumerable };

    // write
    if (originalProperty.set) {// accessor property
        newProperty.set = function(val) {
            if(enabled && (!func || func && func(val)))
                debugger;
            
            originalProperty.set.call(this,val);
        }
    } else if (originalProperty.writable) {// value property
        newProperty.set = function(val) {
            if(enabled && (!func || func && func(val)))
                debugger;

            originalProperty.value = val;
        }
    } else  {
        verifyNotWritable();
    }

    // read
    newProperty.get = function(val) {
          if(enabled && mode === 'read' && (!func || func && func(val)))
            debugger;

        return originalProperty.get ? originalProperty.get.call(this,val) : originalProperty.value;
    }

    Object.defineProperty(obj,newProperty);

    return {
      disable: function() {
        enabled = false;
      },enable: function() {
        enabled = true;
      }
    };
};

enter image description here

例如在控制台中(或在代码段的末尾)输入 breakOn(document.body,'clientWidth','read'),如果在断点处继续执行代码, 然后在控制台中使用 document.body.clientWidth 访问(读取)document.body 对象的属性“clientWidth”。

这应该使代码片段在调试器语句处停止。现在可以使用调用堆栈查看谁或什么更改了属性,在本例中为“匿名”。

enter image description here

,

调试器似乎丢弃使用格式 function foo() {} 定义的函数,但保留使用格式 foo = function() {} 定义的函数。