Вот и это в Javascript и еще несколько:

Ключевое слово this в javascript - это, пожалуй, самая двусмысленная вещь, которую нужно учитывать при написании кода. Иногда это сбивает с толку даже самых опытных разработчиков JavaScript. Эта статья направлена ​​на объяснение всех концепций, связанных с javascript, особенно тех частей, в которых понимание механизма становится сложным. Устройтесь поудобнее и наслаждайтесь путешествием.

this в javascript используется так же, как местоимения в английском языке. Обычно мы пишем «Дженсен изучает javascript, потому что хочет изучить веб-разработку». В данном примере обратите внимание на использование местоимения he для обозначения Иоанна. Местоимение he относится к человеку John. Аналогично в Javascript ключевое слово this действует как референт на объект, который выполняется в текущем контексте.

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

var person = {
    firstName: "Jensen",
    lastName: "Ackles",
    fullName: function () {
        ​//using this
        console.log(this.firstName + " " + this.lastName);
        ​// using object name
        console.log(person.firstName + " " + person.lastName);
    }
}

person.fullName();

В следующем коде работают как this, так и person, однако использование ключевого слова this для ссылки на объект является предпочтительным по двум причинам:

  1. Может присутствовать глобальный объект с тем же именем person, и код может попытаться получить доступ к глобальному объекту.
  2. Иногда имя объекта неизвестно коду, который его выполняет, ключевое слово this упрощает его, добавляя ссылку на объект, который содержит текущий контекст.

Обратите внимание, что ключевое слово this можно использовать глобально, однако в строгом режиме this содержит значение undefined в глобальных функциях и в анонимных функциях, которые не привязаны к какому-либо объекту.

Основы this: прояснение недоразумений

Все функции javascript имеют свойства, точно так же, как объекты содержат свойства. Всякий раз, когда функция выполняется, ей присваивается свойство this с значением объекта, вызывающего функцию. Свойство this ВСЕГДА содержит ссылку на объект и обычно используется внутри функции для доступа к свойствам и методам объекта.

Если мы рассмотрим приведенный выше пример, функция fullName выполняется из объекта person. Свойство this, используемое внутри функции fullName, теперь относится к объекту person.

Большой принцип. Самая важная концепция свойства this, которую нужно понять, заключается в том, что значение this не присваивается до тех пор, пока объект не вызовет функцию. Хотя кажется, что значение this должно быть равно значению объекта, внутри которого определена функция, это неверно. Пока объект не вызовет функцию, в которой используется this, значение не присваивается, а значение this равно значению объекта, вызывающего функцию в большинстве случаев. Однако существуют определенные исключительные сценарии, когда this не имеет значения вызывающего объекта, и эти сценарии будут объяснены позже.

Это в глобальном масштабе:

Значение this, как объяснялось ранее, содержит значение вызывающего объекта. В глобальной области действия код выполняется в браузере, и все глобальные переменные и функции определены в объекте. Следовательно, когда this используется внутри глобальных функций, он содержит значение объекта. Рассмотрим следующий пример:

var firstName = "Dean";
var lastName = "Winchester";
function showFullName() {
    console.log(this.firstName + " " + this.lastName);
}

var person = {
    firstName: "Jensen",
    lastName: "Ackles",
    showFullName: function () {
        console.log(this.firstName + " " + this.lastName);
    }
}

showFullName (); // Dean Winchester - this refers to global window object
window.showFullName (); // Dean Winchester - this refers to window object
person.showFullName (); // Jensen Ackles - this refers to person object

Контекст this можно изменить

Хотя мы сказали, что значение this обычно содержит значение объекта, который вызывает функцию, оно может быть изменено во многих сценариях. Типичные сценарии, когда значение этих изменений:

  • Заимствование метода, использующего this
  • Назначьте метод, использующий this
  • Функция обратного вызова с использованием this.
  • this используется внутри укупорки.

Давайте посмотрим на пример, который демонстрирует возможность, а затем рассмотрим различные сценарии, в которых значение this действует по-разному:

var person1 = {
    firstName: "Jensen",
    lastName: "Ackles",
    showFullName: function () {
        console.log(this.firstName + " " + this.lastName);
    }
}

var person2 = {
    firstName: "Dean",
    lastName: "Winchester",
}

person1.showFullName (); // Jensen Ackles - this refers to person1 object
person1.showFullName.apply(person2); // Dean Winchester - this refers to person2 object

Вы можете видеть, как значение this изменилось просто потому, что мы использовали и принудительно использовали контекст this для person2

this при заимствовании методов:

Заимствование методов - обычная практика в разработке javascript. Иногда методы определены в другом объекте, и мы хотели бы использовать его в нашем объекте, не повторяя код. Учитывая приведенный выше пример:

var person1 = {
    firstName: "Jensen",
    lastName: "Ackles",
    showFullName: function () {
        return this.firstName + " " + this.lastName;
    }
}

var person2 = {
    firstName: "Dean",
    lastName: "Winchester",
}

person2.fullName = person1.showFullName();
console.log(person2.fullName); // Jensen Ackles - this refers to person1 object
person2.fullName = person1.showFullName.apply(person2); 
console.log(person2.fullName); // Dean Winchester - this refers to person2 object

Использование apply во время выполнения метода и предоставление объекта, для которого должно быть установлено значение this, устранит проблемы при заимствовании методов.

this когда метод назначается переменной:

Значение this присваивается контексту другого объекта, когда мы назначаем метод, который используется переменной:

var person = {
    firstName: "Jensen",
    lastName: "Ackles",
    fullName: function () {
        return this.firstName + " " + this.lastName;
    }
}

var showFullName = person.fullName;
console.log(showFullName()); // undefined undefined

Вместо значения «Дженсен Эклз» мы получили «undefined undefined». Это связано с тем, что, когда метод был заимствован, его контекст не установлен в глобальную переменную. Поскольку глобальный объект окна не содержит значений firstName и lastName, они печатаются как неопределенные. Чтобы решить эту проблему, мы можем установить значение this для определенного объекта на неопределенное время, используя bind:

var person = {
    firstName: "Jensen",
    lastName: "Ackles",
    fullName: function () {
        return this.firstName + " " + this.lastName;
    }
}

var showFullName = person.fullName.bind(person);
console.log(showFullName()); // Jensen Ackles

this при использовании внутри метода в качестве обратного вызова:

Значение this выходит из контекста, когда оно используется в функции, предоставляемой как обратный вызов:

var person = {
    firstName: "Jensen",
    lastName: "Ackles",
    fullName: function () {
        console.log(this.firstName + " " + this.lastName);
    }
}

setTimeout(person.fullName, 1000); // undefined undefined

Приведенный выше код работает аналогично тому, как изменяется контекст this, когда он назначается переменной. Можно предположить, что функция setTimeOut имеет переменную, которая принимает функцию в качестве параметра, а затем выполняется на глобальном объекте. Поскольку глобальный объект не содержит определения для firstName и lastName, значение печатается как undefined.

Чтобы исправить это, нам нужно привязать значение this к объекту, к которому оно должно быть применено. Это шаблон, который чаще всего встречается, когда мы определяем функции обратного вызова для событий javascript.

setTimeout(person.fullName.bind(person), 1000); // Jensen Ackles

this при использовании внутри укупорочного средства:

Другой случай, когда значение this неправильно понимается, - это когда this используется внутри замыканий.

var person = {
    fullName: "Jensen Ackles",
    getDetails: function () {
        var closureFunction  =  function() {
            console.log(this.fullName); // undefined
            console.log(this); // global window object
        }
        closureFunction();
    }
}

person.getDetails();

Значение this не относится к объекту person, а скорее к глобальному объекту окна. У нас есть два способа решить эту проблему:

  1. Назначьте значение this явной переменной, а затем используйте эту переменную для доступа к свойствам.
var person = {
    fullName: "Jensen Ackles",
    getDetails: function () {
        var personObj =  this;
        var closureFunction  =  function() {
            console.log(personObj.fullName); // Jensen Ackles
            console.log(personObj); // person Object
        }
        closureFunction();
    }
}

person.getDetails();

2. Используйте стрелочную функцию, предоставленную ES6: стрелочная функция сохраняет контекст this.

var person = {
    fullName: "Jensen Ackles",
    getDetails: function () {
        var closureFunction  = () => {
            console.log(this.fullName); // Jensen Ackles
            console.log(this); // person Object
        }
        closureFunction();
    }
}

person.getDetails();

Эта статья была нацелена на обеспечение подробного понимания того, как this используется в javascript, и предупредила о подводных камнях, которых можно избежать при использовании this. Используя функции JavaScript apply, call, bind и arrow, мы можем управлять значением this в соответствии с нашими потребностями. В заключение, помните, что значением this обычно является объект, для которого вызывается функция.

Первоначально опубликовано на https://aparnajoshi.netlify.app.