Прочитать затенённое приватное поле внешнего класса
Я ожидал, что находясь в классе B я смогу для инстанса класса A прочитать поля #a и #x, однако фактически у меня читается только #a, а при попытке прочитать #x происходит ошибка
Cannot read private member #x from an object whose class did not declare it
Выходит, что поле #x класса B затеняет аналогичное поле класса A? Во-первых, это выглядит как-то нелогично - почему так происходит и, если так задумано, то с какой целью? Во-вторых, есть ли какой-то способ прочитать #x на инстансе класса A?
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 }
Если это важно, я использую Google Chrome 89.0.4389.90.
PS: Этот вопрос на английском.
Ответы (1 шт):
Дам кусочек отсюда
Приватные поля экземпляров объявляются #имя (произносится как "хэш нэймс"), которые идентифицируются префиксом #. # является частью имени, а также используется для объявления и доступа.
Инкапсуляция обеспечивается языком. Обращение к # именам вне области видимости является синтаксической ошибкой.
Вы передали A методу в B
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
Метод пытается вызвать как бы A#x но так как B#x также существует он отказывает в доступе к нему.
Далее Вы передали B методу в В
A.B.doSmth(new A.B)
Cannot read private member #a from an object whose class did not declare it
B#b
B#x
Метод пытается вызвать как бы A#а но так как B не имеет доступа он отказывает в доступе к нему.
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("=== Ну и веселье ===")
console.log("=== A ===")
A.doSmthA(new A.B)
console.log("")
console.log("=== B ===")
A.B.doSmthB(new A)
Если подитожить - приватные поля не видны вне класса и не важно откуда вы их вызываете.