0

During a breakpoint, I define a function in the Console (as described here), but I cannot use it in the Console ("is not defined" error).

Why does a function that I just defined immediately disappear? How can I use it?

root
  • 1,812
  • 1
  • 12
  • 26

2 Answers2

1

How can I use it?

Method 1: First load the page, then run the snippet.

Method 2: define the function breakOn as a variable (anonymous function expression) if you want to successfully define it while a breakpoint is active (pointed out by '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, propertyName, newProperty);

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

      enable: function() {
        enabled = true;
      }
    };
};

enter image description here

E.g. enter breakOn(document.body, 'clientWidth', 'read')in the console (or at the end of the snippet), continue code execution if at a breakpoint, then access (read) the property 'clientWidth' of the document.body object in the console with document.body.clientWidth.

This should make the snippet code stop at the debugger statement. Now the call stack can be used to see who or what changed the property, in this case 'anonymous'.

enter image description here

A.J.Bauer
  • 2,803
  • 1
  • 26
  • 35
  • Re "You can't run a snippet while a breakpoint is active": I disagree. I can for example run `a=1` and then `a+1` yields `2` in the console. So I can define variables. But not both kinds of functions. I'm upvoting though because this helped me make some progress, thanks! – root Jul 31 '21 at 13:13
  • you are right, I change the answer accordingly – A.J.Bauer Jul 31 '21 at 14:18
1

It seems that the debugger discards functions that were defined using the format function foo() {}, but keeps functions that were defined using the format foo = function() {}.

root
  • 1,812
  • 1
  • 12
  • 26