Search code examples
node.jsthisarrow-functions

Arrow function use that is assigned by a module.export object cannot correctly resolve this


It seems that only if I fill out the child object directly in the Base function that is the only way that the getSettings function can see the this.name property correctly, but I was trying to have my objects in different files to avoid having one large file.

***child.js***
module.exports : {
  getSettings: ()=>{
    return this.name === 'foobar'
  }
}

***base.js***
var Child = require('./child.js')
function Base(){
  this.name = 'foobar'
  this.child = Child
  this.child2 = {}
  for (var prop in Child){
    this.child2[prop] = Child[prop]
  }
  this.child3 = {
    getSettings: ()=>{
      return this.name === 'foobar'
    }
  }
}

***index.js****
var Base = require('./base.js')

var b = new Base()
b.child.getSettings() //FAILS BECAUSE this.name is undefined
b.child2.getSettings() //FAILS BECAUSE this.name is undefined
b.child3.getSettings() //PASSES. this.name is defined

Solution

  • It's conventional in JS OOP to refer class instance as this, so it's semantically incorrect for child objects to refer to parent object as this. This also makes it difficult to work with an object like child that doesn't get desirable context as lexical this (like child3 does).

    child object likely should be a class that are injected with parent instance as a dependency.

    module.exports = class Child(parent) {
      constructor(parent) {
        this.parent = parent;
      }
    
      getSettings() {
        return this.parent.name === 'foobar'
      }
    }
    

    var Child = require('./child.js')
    function Base(){
      this.name = 'foobar'
      this.child = new Child(this);
      ...
    }