1

I have a JavaScript variable called

var someProperty;

on line, let's say 10000 (its a huge js file), I have a function

function updateTime() {
     console.log(someProperty.time); //i actually get an value here
}

I want to find out the function that is changing the value of the property I tried setting breakpoint using Chrome dev tools directly on that var someProperty but received a value of "undefined" - which makes me believe a function is setting this variable. How can I find out or watch where this someProperty.time property is being set?

Daniel Li
  • 287
  • 2
  • 17

2 Answers2

1

This is a possible solution

var someProp = {
  time: 'give me'
};

Object.defineProperty(someProp, 'time', {
  set: function(time) {
    this.__time = time
    console.log('Method1: Getting time from:',arguments.callee.caller)
  },
  get: function() {
    return this.__time;
  }
});

(function ILikeChanges() {
  someProp.time = 'changes';
})()
E. Sundin
  • 4,103
  • 21
  • 30
1

Another modern solution would be to use a Proxy object to wrap your object, that will give you the ability to add listeners to updates to your object.

In the set function we are using console.trace to print a full stack trace which will direct you to the calling function.

MDN Proxy

const watchObject = obj => new Proxy(obj, {
  set(target, key, value) {
    console.trace('set', { key, value })
    return target[key] = value
  }
});
// wrap the object with our proxy
const someProperty = watchObject({ time: new Date })

function setTime() {
  someProperty.time = new Date
}
// call the function that changes the state
setTime()
// look in your console for the call stack
synthet1c
  • 6,152
  • 2
  • 24
  • 39
  • I tried a proxy approach with the `arguments.callee.caller` method but that was not allowed. This solution is really cool! – E. Sundin Mar 20 '17 at 01:46
  • Yeah `arguments.callee` is discouraged due to security concerns and will not work in strict mode. `Proxy` isn't available in IE unfortunately so it would need the Proxy shim to work. – synthet1c Mar 20 '17 at 01:54
  • But if some unknown code is changing the property, how would you tell it to use the proxy? –  Mar 20 '17 at 02:02
  • @torazaburo Just replace the object `someProperty = someObject` and make sure it has all the previous fields. – E. Sundin Mar 20 '17 at 02:04
  • I think `set` should always return `true`. –  Mar 20 '17 at 02:28
  • @torazaburo you can return any value from the setter function. – synthet1c Mar 20 '17 at 03:10
  • @torazaburo you can wrap your existing object with the `watchObject` function to decorate it with the proxy. You will not have to change any other line of code. I have updated the answer. I just thought `someProperty` was a bad name and `someObject` was more descriptive. – synthet1c Mar 20 '17 at 03:29