0

How can I access a sibling property from a method in Javascript? It seems like a simple thing to want to do, but I haven't found a way. Specifically, consider the following code.

let f = { 
    a: 3, 
    printMyBrother() { console.log(X) } 
}.printMyBrother

f()

What must I change X to in the above code, in order to programatically log "3" on the console?

Bruce Bartlett
  • 213
  • 2
  • 5
  • Store your object in another variable (eg `o`) and reference `o.a` – Phil May 05 '20 at 01:33
  • That has not answered the question. – Bruce Bartlett May 05 '20 at 01:39
  • That's why it's not in the answer section below – Phil May 05 '20 at 01:39
  • 3
    Given the literal code above, what you want is not possible. If `f` were your object and you called `f.printMyBrother()`, you could use `this.a` but since you're referring directly to the `printMyBrother` function, all context of that original object is lost – Phil May 05 '20 at 01:42
  • 1
    It seems very strange to me that this is not possible. Many languages have a "self" keyword that will reference the containing object. In those languages, we could just substitute X -> self.a. Even in HTML, we can do this, using the parentElement property. I don't understand why we are not able to do this in Javascript. – Bruce Bartlett May 05 '20 at 01:45
  • 2
    You're not going to get a good answer for that question here. You could try asking Crockford but he probably won't answer. In the meantime, these might help... [What does it mean that Javascript is a prototype based language?](https://stackoverflow.com/q/186244), [Difference between classical inheritance and prototype inheritance](https://stackoverflow.com/q/34707632) – Phil May 05 '20 at 01:51
  • Ok. Who is Crockford? I took a look at your links, and eventually landed up learning about the "compositional approach" to object oriented programming, which is interesting, so thanks for that. – Bruce Bartlett May 05 '20 at 12:24
  • https://en.m.wikipedia.org/wiki/Douglas_Crockford – Phil May 05 '20 at 22:05

1 Answers1

-1

You can do it if you change your code a little bit:

This is an example of different ways that this would work. The reason it works this way is due to interesting rules of javascript's this.

let f = {
  a: 3,
  printMyBrother(message) {
    console.log(message, this.a)
  }
}
let printMyBrother = f.printMyBrother;


console.group('function');
console.log('function');
f.printMyBrother('function call')

// The printMyBrother won't work alone without being bound
printMyBrother('unbound function call');

// Bind printMyBrother variable to always refer to f
printMyBrother = printMyBrother.bind(f);
printMyBrother('bound function call')
console.groupEnd();


class ClassF {
  a = 3;
  // This is unbound to the class by default
  // because it's not an arrow function
  // You can bind it in the constructor manually, however
  printMyBrotherUnbound(message) {
    console.log('classF', message, this.a)
  };
  // This is bound to the class by default
  // because it's an arrow function
  // This should work in all major browsers (besides IE)
  printMyBrotherBound = (message) => {
    console.log('classF', message, this.a)
  }
}


let classF = new ClassF();
console.group('Class Method')
console.log('Class Method')
printMyBrother = classF.printMyBrotherUnbound;
classF.printMyBrotherUnbound('in class');
try {
  printMyBrother('unbound');
} catch (error) {
  console.log('unbound class function errors out because this is undefined');
}
console.groupEnd()

console.group('Class Arrow Function');
console.log('Class Arrow Function');
printMyBrother = classF.printMyBrotherBound;
classF.printMyBrotherBound('arrow function');
printMyBrother('unbound arrow function');
console.groupEnd();

Some resources on the this keyword in JavaScript:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

https://www.javascripttutorial.net/javascript-this/

Zachary Haber
  • 10,376
  • 1
  • 17
  • 31