Укр
Ключевое слово this — это просто

Ключевое слово this — это просто

  • 12 июля, 2023
  • читать 7 мин
Александра Донцова
Александра Донцова Front-end Developer в Sigma Software, Преподаватель Компьютерной школы Hillel.

JavaScript является одним из самых популярных языков программирования в мире, он широко используется для разработки веб-приложений.

Одной из важнейших концепций JavaScript является ключевое слово «this». Оно используется для ссылки на текущий объект в контексте кода. Хотя сначала может показаться, что «this» — это сложная тема, на самом деле изучить ее не так уж трудно.

И я вас уверяю, что после прочтения этой статьи у вас не останется вопросов насчет этого! :-)

Итак, поехали:

THIS в методе объекта

This часто используют в объектных литералах.

Объектные литералы — это быстрый способ создания объектов в JavaScript. В этом контексте «this» указывает на объект, в котором он находится.

Рассмотрим пример:

const person = {
    name: "John",
    age: 25,
    sayHello: function () {
        console.log(`Привіт, я ${this.name}`);
    },
};


person.sayHello(); // Виведе "Привіт, я John"

В этом примере мы создаем объект person со свойствами name и age, а также методом sayHello. В методе sayHello мы используем «this» для ссылки на объект person и вывод значения свойства name.

THIS в классах

Другим частым использованием «this» является контекст функций-конструкторов.

Функции-конструкторы используются для создания новых объектов на основе шаблона. В таком контексте «this» указывает на создаваемый объект.

Рассмотрим следующий пример:

function Person(name, age) {
    this.name = name;
    this.age = age;
}


const john = new Person("John", 25);
console.log(john.name); // Виведе "John"
console.log(john.age); // Виведе 25

В этом примере функция-конструктор Person имеет два параметра — name и age. Когда мы создаем новый объект с помощью оператора new, «this» указывает на этот объект. Поэтому свойства name и age присваиваются именно этому объекту.

THIS в функциях

Использование «this» может быть не столь очевидным, когда его используют в обычных функциях или связанных методах. В обычных функциях this обычно указывает на глобальный объект window (в браузере) или глобальный объект global (в среде Node.js).

К примеру:

function greet() {
    console.log(`Привіт, я ${this}`);
}


greet(); // Виведе "Привіт, я [object Window]" (у браузері)

В этом примере «this» указывает на глобальный объект window, поскольку функцию greet вызывают в глобальном контексте.

Чтобы понять значение «this» в связанных методах, нужно обратить внимание на контекст вызова. Контекст вызова — это объект, на котором вызывается метод. Для правильного использования «this» в связанных методах можно использовать методы bind, call или apply.

К примеру:

const person = {
    name: "John",
    age: 25,
};


function sayHello () {
    console.log(`Привіт, я ${this.name}`);
}


sayHello.call(person);  // Виведе "Привіт, я John"

В этом примере мы используем метод call для привязки к контексту функции объекта sayHello person. Это позволяет сохранить правильный контекст "«this» независимо от того, каким образом вызывается метод.

THIS в стрелочной функции

В стрелочных функциях в JavaScript «this» имеет особое поведение. Они не имеют собственного значения «this» и берут его из контекста, в котором они были созданы. Это означает, что «this» в стрелочной функции будет иметь такое же значение, как и «this» во внешней области видимости, где она была объявлена.

Вот пример, чтобы продемонстрировать это:

// Зовнішня функція, яка містить стрілкову функцію
function outerFunction() {
    // Властивість "name" належить об'єкту, у якому викликається зовнішня функція
    this.name = "John";


    // Стрілкова функція внутрішня до зовнішньої функції
    const innerArrowFunction = () => {
        // Виведе "John", беручи значення "this" з контексту зовнішньої функції
        console.log(this.name);
    };


    innerArrowFunction(); // Виклик стрілкової функції
}


outerFunction(); // Виклик зовнішньої функції

В этом примере стрелочная функция innerArrowFunction берет значение «this» из контекста внешней функции outerFunction, поскольку она была объявлена внутри нее. Поэтому когда мы вызовем innerArrowFunction, она выведет «John», поскольку this.name ссылается на name во внешней функции.

Важно отметить, что стрелочные функции не могут быть использованы в качестве функций-конструкторов и не имеют собственного значения «this». Поэтому они не подходят для использования в ситуациях, когда нужно контролировать значение «this» или использовать ключевые слова, такие как super или arguments.

THIS в анонимной функции

В анонимных функциях JavaScript поведение «this» зависит от контекста, в котором они были вызваны. Они не имеют собственного значения «this» и получают его из родительского контекста.

Вот пример, чтобы продемонстрировать это:

// Об'єкт, який містить метод і анонімну функцію
const obj = {
    name: "John",
    sayHello: function () {
        console.log(`Hello, ${this.name}`);
        // Виводить "Hello, John" - this посилається на об'єкт obj


        (function () {
            console.log(`Inside anonymous function: ${this.name}`);
            // Виводить "Inside anonymous function: undefined" - this не має власного значення
        })();
    }
};


obj.sayHello(); // Виклик методу sayHello

В этом примере метод sayHello имеет доступ к this.name, поскольку он был вызван на объекте obj. Однако анонимная функция внутри метода sayHello не имеет собственного значения «this». Поэтому когда мы попытаемся вывести this.name внутри анонимной функции, она выведет undefined, поскольку this отсутствует в контексте этой функции.

Для доступа к родительскому контексту, где this соответствует ожидаемому объекту, можно сохранить ссылку на «this» в переменной, которую затем можно использовать внутри анонимной функции.

К примеру:

const obj = {
    name: "John",
    sayHello: function () {
        const self = this; // Зберегти посилання на this у змінній self
        (function () {
            console.log(`Inside anonymous function: ${self.name}`); // Виведе "Inside anonymous function: John"
        })();
    }
};


obj.sayHello(); // Виклик методу sayHello

Использование переменной self позволяет получить доступ к ожидаемому значению «this» внутри анонимной функции

А в чем разница между THIS в стрелочной и анонимных функциях?

Главная разница между «this» в стрелочной функции и анонимной функции JavaScript заключается в их поведении относительно привязки «this».

В стрелочных функциях:

  1. Они не имеют собственного значения «this». Они принимают значение «this» из контекста, в котором они были созданы. Это означает, что this в стрелочной функции будет иметь такое же значение, как this во внешнем объеме видимости, где она была объявлена.
  2. Они не могут быть использованы как функции-конструкторы. Поэтому нельзя создать экземпляр объекта с помощью стрелочной функции.
  3. Они не имеют доступа к ключевым словам super и arguments.
  4. Они удобны для использования в контекстах, где нужно иметь доступ к значениям «this» из внешнего контекста.

С другой стороны, в анонимных функциях:

  1. Они могут иметь собственное значение «this», определяемое контекстом вызова. Значение «this» в анонимной функции зависит от того, как именно она была вызвана.
  2. Они могут быть использованы в качестве функций-конструкторов для создания новых объектов.
  3. Они имеют доступ к ключевым словам super и arguments, которые позволяют получать доступ к родительским объектам и аргументам функции соответственно.
  4. Они удобны для использования в контекстах, где нужно динамически привязать значение «this» к вызывающему объекту.

Как определять «this» в JavaScript?

Итак, для определения «this» в JavaScript можно выделить следующую схему:

  • Вызывается ли глобальная функция?

Да: «this» ссылается на глобальный объект (например, window в браузере или global в Node.js).

  • Вызывается ли функция-метод объекта?

Да: «this» ссылается на объект, на котором была вызвана функция.

  • Вызывается функция-конструктор с помощью new?

Да: «this» ссылается на вновь созданный объект, созданный функцией-конструктором.

  • Используется метод call, apply или bind?

Да: «this» устанавливается явно через первый аргумент метода call, apply или bind.

  • Используется ли стрелочная функция?

Да: «this» берется из родительского контекста, где она была создана, и не может быть изменена.

  • Используется ли анонимная функция?

Зависит от контекста, в котором анонимная функция была вызвана. Это может быть глобальный объект, объект, на котором была вызвана функция, или может быть собственное значение «this», установленное явно.

Это и есть общая схема для определения «this» в JavaScript. При рассмотрении конкретных случаев важно учитывать контекст вызова и особенности использования методов и функций в коде.

Надеюсь после этих разъяснений вы больше никогда не потеряете свое «это».

Благодарю за внимание! :-)

Рекомендуем курс по теме