Почему ключевое слово super указывает на неопределенность в классе ES6? - PullRequest
0 голосов
/ 05 июня 2019

Я новичок в классах ES6 и пытаюсь понять, как в нем работает наследование.Я создал родительский класс Modal и дочерний класс ChildModal, например:

class Modal {
    constructor(selector, document) {
        this.selector = selector;
        this.document = document;
    }

    get title() {
        return this._title;
    }

    set title(title) {
        if(!title) {
            throw new Error('Original title cannot be empty');
        }
        this._title = title;
    }

    defineNewTitle(newContent) {
        this.title = newContent + this.title;
    } 

    assignNewTitle() {
        $(this.selector).text(this.title);
    }
}

var modal = new Modal("#mainTitle");

modal.title = "Standards";

modal.defineNewTitle("JavaScript ");

modal.assignNewTitle();

class ChildModal extends Modal {
    constructor(selector, title) {
        super(selector, title);
    }

    defineChildTitle(title) {
        this.title = title + this.title;
    }

    assignChildTitle() {
        $(this.selector).text(this.title);
    }
}

var child = new ChildModal("#childTitle");
child.defineChildTitle("Wow ");
child.assignChildTitle();
<!DOCTYPE html>
<html>
<head>
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
	<title>Class test</title>
	<h1 id="mainTitle">
		Main title
	</h1>
	<h2 id="childTitle">
		Child title
</head>
<body>
	<script src="Modal.js"></script>
</body>
</html>

Я ожидаю, что тег h2 будет изменен на «Стандарты Wow JavaScript», но вместо этого он выдаст «Wow undefined».Почему в методе defineChildTitle он не распознает this.title?Мысль в классе childModal, this.title должна быть 'Стандарт JavaScript as I've inherited the Модальный class in the constructor? введите код здесь *

Ответы [ 3 ]

2 голосов
/ 05 июня 2019

Поля класса, такие как заголовок, селектор и документ, не разделяются между экземплярами.Поэтому, когда вы присваиваете заголовок своей переменной modal, это не влияет на другие значения или классы.

Когда ChildModal вызывает super(selector, title), он передает свой аргумент заголовка инициализатору Modal,В классе Modal оно сохраняется в поле document.

Когда вы запускаете this.title = title + this.title;, поле заголовка не имеет никакого значения.Это undefined.Таким образом, заголовок заканчивается на "Wow" + undefined, что приводит к "Wow undefined".

1 голос
/ 05 июня 2019

Вы должны определить _title в своем конструкторе:

class Modal {
    constructor(selector, document) {
        this.selector = selector;
        this.document = document;
        this._title = ''
    }
}

var child = new ChildModal("#childTitle");
child.title = "JavaScript Standards"
child.defineChildTitle("Wow ");
child.assignChildTitle();

В настоящее время вы присоединяетесь к string с undefined, что приводит к undefined.

Поскольку высоздаем два экземпляра, они не связаны друг с другом, поэтому child.title - это не то же самое, что modal.title, поэтому их объединение приведет к двум различным строкам.

Итак, вы не тольконужно установить заголовок в modal.title = 'JavaScript Standards', но вы также должны установить то же самое в child.title = 'JavaScript Standards'.

class Modal {
    constructor(selector, document) {
        this.selector = selector;
        this.document = document;
        this.title = ' '
    }

    get title() {
        return this._title;
    }

    set title(title) {
        if(!title) {
            throw new Error('Original title cannot be empty');
        }
        this._title = title;
    }

    defineNewTitle(newContent) {
        this.title = newContent + this.title;
    } 

    assignNewTitle() {
        $(this.selector).text(this.title);
    }
}

var modal = new Modal("#mainTitle");

modal.title = "Standards";

modal.defineNewTitle("JavaScript ");

modal.assignNewTitle();

class ChildModal extends Modal {
    constructor(selector, title) {
        super(selector, title);
    }

    defineChildTitle(title) {
        this.title = title + this.title;
    }

    assignChildTitle() {
        $(this.selector).text(this.title);
    }
}

var child = new ChildModal("#childTitle");
child.title = "JavaScript Standards"
child.defineChildTitle("Wow ");
child.assignChildTitle();
<!DOCTYPE html>
<html>
<head>
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
	<title>Class test</title>
	<h1 id="mainTitle">
		Main title
	</h1>
	<h2 id="childTitle">
		Child title
</head>
<body>
	<script src="Modal.js"></script>
</body>
</html>
0 голосов
/ 05 июня 2019

Под капотом классы ES5 по-прежнему используют прототип .

Таким образом, другое решение может быть изменено modal.title = "Standards"; на Modal.prototype.title = "Standards";.

Таким образом, вы не измените свойство в экземпляре, но вы измените значение впрототип (он же определение класса):

class Modal {
    constructor(selector, document) {
        this.selector = selector;
        this.document = document;
    }

    get title() {
        return this._title;
    }

    set title(title) {
        if(!title) {
            throw new Error('Original title cannot be empty');
        }
        this._title = title;
    }

    defineNewTitle(newContent) {
        this.title = newContent + this.title;
    } 

    assignNewTitle() {
        $(this.selector).text(this.title);
    }
}

var modal = new Modal("#mainTitle");

Modal.prototype.title = "Standards";

modal.defineNewTitle("JavaScript ");

modal.assignNewTitle();

class ChildModal extends Modal {
    constructor(selector, title) {
        super(selector, title);
    }

    defineChildTitle(title) {
        this.title = title + this.title;
    }

    assignChildTitle() {
        $(this.selector).text(this.title);
    }
}

var child = new ChildModal("#childTitle");
child.defineChildTitle("Wow ");
child.assignChildTitle();
<!DOCTYPE html>
<html>
<head>
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
	<title>Class test</title>
	<h1 id="mainTitle">
		Main title
	</h1>
	<h2 id="childTitle">
		Child title
</head>
<body>
	<script src="Modal.js"></script>
</body>
</html>
...