Read shadowed private field of the outer class

118 Views Asked by At

I expected that being inside of class B I can read private fields #a and #x of class A. But in fact I can read only #a, in case of access to #x I get an error:

Cannot read private member #x from an object whose class did not declare it

Seems like #x of class B shadows similar field of A. First of all it seems illogical - why does it work in such way and if it is intentional, way was it planned in such way? And is it possible to read #x on A instance being inside of B?

class A {
  #a = "A#a"
  #x = "A#x"

  static B = class B {
    #b = "B#b"
    #x = "B#x"

    static doSmth(obj) {
      try { console.log(obj.#a) } catch (e) { console.log(e.message) }
      try { console.log(obj.#b) } catch (e) { console.log(e.message) }
      try { console.log(obj.#x) } catch (e) { console.log(e.message) }
    }
  }
}

console.log("=== A ===")
A.B.doSmth(new A)
console.log("")
console.log("=== B ===")
A.B.doSmth(new A.B)
.as-console-wrapper.as-console-wrapper { max-height: 100vh }
.as-console-row.as-console-row:after { content: none }

I'm using Google Chrome 89.0.4389.90 if it matters.

PS: Same question in Russian.

1

There are 1 best solutions below

0
On

Give a part from here

Like their public equivalent, private static methods are called on the class itself, not instances of the class. Like private static fields, they are only accessible from inside the class declaration.

You pass A into B method doSmth

A.B.doSmth(new A)

A#a
Cannot read private member #b from an object whose class did not declare it
Cannot read private member #x from an object whose class did not declare it

Method have no access A#x since B#x also declared and A have no access to it.

Next you pass B into B method doSmth

A.B.doSmth(new A.B)

Cannot read private member #a from an object whose class did not declare it
B#b
B#x

Method B have no acess to A#а

class A {
  #a = "A#a"
  #b = "A#b"
  #x = "A#x"
  
  static doSmthA(obj) {
      try { console.log(obj.#a) } catch (e) { console.log(e.message) }
      try { console.log(obj.#b) } catch (e) { console.log(e.message) }
      try { console.log(obj.#x) } catch (e) { console.log(e.message) }
  }

  static B = class B {
    
    #a = "B#a"
    #b = "B#b"
    #x = "B#x"

    static doSmthB(obj) {
      try { console.log(obj.#a) } catch (e) { console.log(e.message) }
      try { console.log(obj.#b) } catch (e) { console.log(e.message) }
      try { console.log(obj.#x) } catch (e) { console.log(e.message) }
    }
  }
}

console.log("=== A ===")
A.doSmthA(new A)
console.log("")
console.log("=== B ===")
A.B.doSmthB(new A.B)

console.log("=== NEXT ===")

console.log("=== A ===")
A.doSmthA(new A.B)
console.log("")
console.log("=== B ===")
A.B.doSmthB(new A)