2

Is it possible to deeply self reference within a JS object?

I know it is possible to self reference at the same level, like so:

var foo = {
  a: 'bar',
  b: 'baz',
  c: () => {
    return this.a + this.b;
  }
};
console.log(foo.c()); // barbaz

I'm just curious if it would be possible to do so from deeper down...

var foo = {
  a: 'bar',
  b: 'baz',
  c: {
    ca: 'hello',
    cb: () => {
          return this.a + this.b;
        }
    }
};
console.log(foo.c.cb()); // barbaz

If not... How would one go about getting this to work?

adiga
  • 34,372
  • 9
  • 61
  • 83
physicsboy
  • 5,656
  • 17
  • 70
  • 119

2 Answers2

2

One solution is to call your cb method with foo object as a context then this will refer to foo and a and b will be found, but then you should use regular function instead of arrow function.

var foo = {
  a: 'bar',
  b: 'baz',
  c: {
    ca: 'hello',
    cb: function() {
      return this.a + this.b;
    }
  }
};

console.log(foo.c.cb.call(foo));

Another solution is to turn c into getter and then you can use arrow functions as context will be context of the getter which is root object in this case.

var foo = {
  a: 'bar',
  b: 'baz',
  get c() {
    return {
      ca: 'hello',
      cb: () => {
        return this.a + this.b;
      }
    }
  }
};

console.log(foo.c.cb());
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
  • 1
    alternatively you can just reference foo direct instead of relying on `this` like `return foo.a + foo.b;` – Rikin Dec 19 '19 at 14:57
0

You would have to create a function that returns a referenced "self".

You can apply the new properties to this by referencing the scope at the top level.

let foo = createFoo();
let bar = Object.assign(createFoo(), {
  a : 'zam',
  b : 'zip'
});

console.log(foo.c.cb()); // barbaz
console.log(bar.c.cb()); // zamzip (extended foo)

function createFoo() {
  let self = {}; // Create a new scope.
  return Object.assign(self, {
    a: 'bar',
    b: 'baz',
    c: {
      ca: 'hello',
      cb: () => self.a + self.b
    }
  });
}
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132