Monday, 3 September 2018

Behaviour of callstack and this during .defineProperty method

Pre-face:

Feel free to skip to the actual question below, if you find the 'backstory' here unnecessary. But I do believe it adds good amount of detail and further context for the question

Recently I've been experimenting with objects and the [[ Prototype ]] chain a little,

First, I was baffled as to why my this reference returned in a NaN with the following code:

var obj = {
  a: 2
}

Object.defineProperty(obj, 'b', {
  value: this.a + 2,
  enumerable: true
});

console.log(obj.b);

First, I was baffled as to why, but then an occurance hit me of the NaN behaviour.
My obj.b is calculated as undefined + 2, hence returning in NaN

Now, obviously changing the code do explicit reference of value: obj.a + 2 will do the trick, but I wanted to investigate further as to why this.a returns as undefined.


Basically, my issue was that the my callstack was referencing Object.prototype.a, because Object.defineProperty is implicity delegated Object.prototype.defineProperty.

So, explicity setting a as a property of the Object.prototype would fix the issue:

var obj = {
  a: 2
}

Object.prototype.a = obj.a;

Object.defineProperty(obj, 'b', {
  value: this.a + 2,
  enumerable: true
});

console.log(obj.b);

This returns the expected result of 4 (although yes, creating a property a to entire Object.prototype is definitely not the best programming practice, but for illustration purposes it will serve just fine)

The question:

However, what confuses me is, if I run a console.trace on the expression, my call-stack consists purely of (anonymous) - so basically the global (default) implicit binding for this keyword.

You will have to run the code in your own console, as sadly console.trace() is unfortunately not supported by jsfiddle (least to my knowledge)

var obj = {
  a: 2
}

Object.prototype.a = obj.a;

console.trace(Object.defineProperty(obj, 'b', {
  value: this.a + 2,
  enumerable: true
}));

enter image description here


TL/DR:

So to sum this question up into two quick bulletpoints:

  1. Why does call-stack return only (anonymous) and not also Object.prototype
  2. What would be the proper way to explicitly bind this to the referenced object obj in our .defineProperty() method?

Thank you in advance.



from Behaviour of callstack and this during .defineProperty method

No comments:

Post a Comment