Как получить доступ к переменной экземпляра внешнего класса из внутреннего класса?

#javascript #class

Вопрос:

Допустим, у меня есть следующий код:

 class Cookie{
    ChocolateChip = class{
        constructor(){
            
        }
        sayMyOuterClassName(){
            console.log(???);
        }
    }
    constructor(name){
        this.name = name;
        this.someInstance = new this.ChocolateChip();
        this.someInstance.sayMyOuterClassName();
    }
}

let aCookie = new Cookie("Bob");
 

Чем мне ??? заменить, чтобы он был распечатан "Bob" ? Я видел кого-то рекомендовать Cookie.this.name , но я боюсь попробовать что, не зная всех последствий, так как мне приходится полагаться на код, который я пишу прямо сейчас, и если она сломается в будущем я не хочу, чтобы это было, потому что я использовал эту строку кода, которую я не до конца понимаю, и в конечном итоге тратить много времени.

Помимо этого вопроса, я также хочу задать… Ранее я объявлял свои классы статическими и использовал их подобным new OuterClassName.InnerClassName() образом , но я переключился, потому что предполагал, что это помешает мне получить доступ к переменным экземпляра из моего внешнего класса внутри внутренних классов… Это правильно? Предотвращает ли объявление внутреннего класса статическим доступ к переменным внешнего класса?

Комментарии:

1. «Я видел, как кто-то предложил Cookie.this.name » Это работает не во всех реализациях, которые я тестировал.

Ответ №1:

Добавьте ссылку на родителя:

 class Cookie{
    ChocolateChip = class {
        constructor(parent){
            this.parent = parent;
        }
        sayMyOuterClassName(){
            console.log(this.parent.name);
        }
    }
    constructor(name){
        this.name = name;
        this.someInstance = new this.ChocolateChip(this);
        this.someInstance.sayMyOuterClassName();
    }
}

let aCookie = new Cookie("Bob"); 

Комментарии:

1. Я боялся именно этого… Я действительно не хотел, чтобы это было лучшим решением.

2. @OOPSStudio Почему? Это очень распространенный шаблон во многих языках программирования.

3. Вероятно, вы правы. Для меня это просто кажется очень загромождающим мой код, и это означает, что мне нужно перенастроить некоторые аргументы, чтобы расположить это обязательное поле среди других необязательных полей, и я просто знаю, что это будет стоить мне времени в будущем, зная мою структуру. Но я просто приспособлюсь, я думаю. Спасибо вам за ответ!

Ответ №2:

Чем мне ??? заменить, чтобы он был распечатан "Bob" ?

Ничего, вы не можете сделать это в JavaScript без внесения дальнейших изменений в свой код. Между и не существует внутренней связи Cookie ChocolateChip , кроме того, что свойство экземпляра в Cookie экземпляре ссылается на экземпляр ChocolateChip . Cookie.this.name Синтаксис, который вы видели, был Java, а не JavaScript. Java и JavaScript сильно отличаются в этом отношении.

Возможно, вы неправильно понимаете синтаксис, который используете для создания ChocolateChip . Это не объявление «внутреннего класса» (в JavaScript их нет). Это просто создание свойства экземпляра и назначение class ему выражения с помощью предлагаемого синтаксиса свойств общедоступного класса, который по-прежнему является всего лишь предложением (хотя и очень далеко). Ваш код функционально идентичен этому:

 class Cookie{
    constructor(name){
        this.ChocolateChip = class{
            constructor(){
                
            }
            sayMyOuterClassName(){
                // console.log(???);
            }
        };
        this.name = name;
        this.someInstance = new this.ChocolateChip();
        this.someInstance.sayMyOuterClassName();
    }
}

let aCookie = new Cookie("Bob");
 

Он создает новый ChocolateChip класс для каждого экземпляра Cookie , а затем создает экземпляр этого нового класса. Но нет никакой обратной связи с ChocolateChip Cookie тем, что реализовано самим языком.

Комментарии:

1. Я знаю, что Java и JavaScript очень разные. Однако вопрос, ответ на который содержал это, был помечен JavaScript… Но, возможно, это была ошибка со стороны ответчика.

2. @OOPSStudio — Я так подозреваю, да.

3. На самом деле я ничего не «менял», я просто исправил опечатку. Ваш ответ не «касался темы», он просто выявил опечатку… Так что я бы на самом деле не рассматривал исправление опечатки как «фундаментальное изменение моего вопроса», но ладно. Кроме того, я не понизил ваш ответ, однако я также не буду его повышать, поскольку это не тот ответ, который я ищу, а также не особенно полезен.

4. @OOPSStudio — Нет, это не опечатка. Это вызвало то, что представлялось фундаментальным недоразумением. Это соответствовало убеждению, что у JavaScript есть внутренние классы, такие как Java, которые были очевидны в других местах, поэтому я рассмотрел это недоразумение с разных точек зрения. Мне жаль, что вы не находите полезным объяснить взаимосвязь между этими двумя классами.