Самая большая ошибка JavaScript ООП
Объектно-ориентированное программирование очень просто для большинства языков ООП, но JavaScript немного отличается.
Учитывая функцию создателя игры, мы хотим расширить game
объект, поэтому у него есть несколько дополнительных методов для увеличения счета game.scorePoint()
.
Вы можете использовать es6консоль для проведения наших экспериментов.
Давайте посмотрим код:
function GameCreator(score) {
this.score = score;
}
GameCreator.prototype.scorePoint = function() {
function incrementScore() {
this.score++;
}
incrementScore();
};
GameCreator.prototype.endGame = function() {
console.log(`Game has finished ${this.score}`)
};
let game = new GameCreator(0);
game.scorePoint();
После выполнения этого кода вы заметите, что game.score
все еще 0
. Но почему? Что случилось? Наш код неверен?
Да, это неправильно (но выглядит нормально, правда?). Сначала давайте поймем, почему это неправильно. Оказывается this
из this.score++
представляет window
объект не тот game
пример. ХА! Попался! Это означает, что наш score
где-то теряется в window
.
Итак, идея этого примера состоит в том, чтобы понять, что вложенная функция не будет искать экземпляр, в нашем случае game
пример. Представьте на мгновение, что scorePoint
не только имеет incrementScore
но и printScore
но почему бы и другую функцию endGameWhenMaXScore
. Видеть? Функцию можно разделить на маленькие, что очень здорово, так как помогает организовать код, каждая функция отвечает за одну мелочь.
Теперь, чтобы решить проблему… мы можем использовать Стрелочные функции:
function GameCreator(score) {
this.score = score;
}
GameCreator.prototype.scorePoint = function() {
const incrementScore = ()=> {this.score++};
incrementScore();
};
GameCreator.prototype.endGame = function() {
console.log(`Game has finished ${this.score}`)
};
let game = new GameCreator(0);
game.scorePoint();
С помощью Arrow Function
мы указываем, что хотим использовать game
экземпляр вместо window
.
В настоящее время game.score;
вернется 1
.
Использование метода конструктора:
function GameCreator(score) {
constructor (score) {
this.score = score;
}
increment() {
this.score++;
}
endGame(){
console.log(`Game has finished ${this.score}`)
}
}
let game = new GameCreator(0);
game.increment();
game.endGame();
Использование классов ES6 Классы — JavaScript | МДН:
class Game {
constructor (score) {
this.score = score;
}
increment() {
this.score++;
}
endGame(){
console.log(`Game has finished ${this.score}`)
}
}
let game = new Game(0);
game.increment();
game.endGame();
Посмотреть код бегу сюда
Разве это не красиво? Мне нравится, тебе нравится, всем нравится.
Итак, мы узнали, что this
может быть очень сложным, но управляемым. Вам просто нужно понять this
на каждом контексте.
Попробуйте поэкспериментировать с this
ключевое слово в разных контекстах и анализировать результаты. Это поможет вам понять, как это работает. В конце вы избежите множества ошибок и станете лучшим JS-разработчиком!