0

In a project I'm working on, I'm using Object.defineProperty to define getter and setter methods on some properties, in order to handle specific cases of parsing data. For example:

  module.exports = function() {
    Object.defineProperty(this.body, 'parsed', {
      get: function() {
        ...
        switch(this.type) { // Undefined

        }
    });

    if (this.type) { // Defined correctly
      ...
    }
  }

This would work fine if I was setting this.type within the object instantiation function (i.e. I call var foo = new bar()). However, I set this.type using Object.defineProperty on the module.exports.prototype:

Object.defineProperty(module.exports.prototype, 'type', {
  get: function() {
    ...
    if (this._type) {
      return this._type;
    }
  }
});

In this case, I know that this._type is set, so this.type should return the expected value, but when I attempt to switch it in the first block of code, this.type is undefined. Strangely, when I call it from outside of the Object.defineProperty function, it is defined and returns the correct type.

Is there any way I can access this.type from within the original Object.defineProperty call?

josh
  • 9,656
  • 4
  • 34
  • 51
  • it would help if you'd provide more context. What is `this` in the first block of code? – Pointy Jan 14 '15 at 21:02
  • 2
    `this` inside of the `get` function is `this.body`. When you access `this.body.parsed`, the `get` function is called with a `this` of the member's owning object; here, `this.body`. The traditional solution is to capture the outer value of `this` in a variable, and then the function (called with a different `this` value) can access the desired value normally as an outer-scope variable. See [How to access the correct `this` / context inside a callback?](http://stackoverflow.com/q/20279484/710446) (there are lots of related questions; it's difficult to decide which one best fits your question) – apsillers Jan 14 '15 at 21:02
  • @apsillers Oh I understand. I didn't realize that the scope was changed to `this.body` and thought it stayed as `this`. So I would need to do something like `var self = this;` and then call that `self` from within the `Object.definePrototype(this.body...` call? – josh Jan 14 '15 at 21:04
  • 1
    @JoshuaSmock: Yes, exactly. Or you `.bind()` it. – Bergi Jan 14 '15 at 21:07
  • Ah perfect, that fixed the issue I was having. Thanks @apsillers! If you want to make an actual answer I'll accept it. – josh Jan 14 '15 at 21:13
  • @Bergi ah that's true, but I'm not sure it would work in this case. I guess I could do something like `var foo = new bar(); foo.body.parsed.bind(foo)` ? – josh Jan 14 '15 at 21:20
  • No, it would be in the definition: `{get: function(){…}.bind(this)}` – Bergi Jan 14 '15 at 21:26

0 Answers0