Здесь я собираюсь рассказать, как ключевое слово this играет роль в javascript. Я потратил довольно много времени, чтобы прочитать и понять это из различных ресурсов, включая одну из самых известных книг всех времен о js.

Итак, прежде всего, что такое "это"?

Когда мы создаем и выполняем функцию, JS привязывает новое свойство к функции с именем «this». Мы также можем сказать, что «this» — это контекст выполнения функции в данный момент времени. Значение, связанное с «this», определяется местом вызова этой функции. Call-Site относится к тому, как вызывается функция.

function animal(){
  console.log(this.name)
}
var name = "Cow";
animal(); // Cow

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

Значение, привязанное к «this», определяется следующими правилами:
1. Привязка по умолчанию (указанная выше)
2. Неявная привязка
3. Явная привязка
4. новая привязка

Неявное связывание:

function eat(){
   console.log(this.name + " is eating "+ this.food);
 }
 var animal = {
   name : "cow",
   food : "grass",
   eat : eat
 }
 animal.eat() // cow is eating grass

Здесь мы присвоили ссылку функции eat свойству eat объекта animal . Таким образом, когда мы вызываем функцию с точечной нотацией, "this" вызываемой функции будет привязана к вызывающему объекту. В нашем случае, Функция eat«this» связана с объектом животное.

Явная привязка:

Допустим, у нас есть объект alien с тем же свойством, что и у объекта animal, но мы не хотим дублировать тот же метод eat в инопланетный объект. В этом случае мы можем позаимствовать метод съесть для инопланетного объекта.

function eat(){
   console.log(this.name + " is eating "+ this.food);
}
var alien = {
   name : "xxx",
   food : "bla bla"
}
//reuse the eat method to alien object 
eat.call(alien) // xxx is eating bla bla

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

новая привязка:

Допустим, у нас есть животноводческая ферма, на которой выращиваются разные виды животных.

function eat(){
   console.log(this.name + " is eating "+ this.food);
}
function Animal(name, food){
 this.name = name;
 this.food = food;
 this.eat = eat;
}
var cow = new Animal("Cow","grass");
cow.eat(); //Cow is eating grass
var tiger = new Animal("Tiger","meat");
tiger.eat(); //Tiger is eating meat

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

с помощью этих правил мы можем переписать функцию Animal для создания разных видов животных без использования ключевого слова new.

function eat(){
   console.log(this.name + " is eating "+ this.food);
}
function Animal(name, food){
 var newObj = {}; // step 1
 Object.setPrototypeOf(newObj, Animal.prototype); // step 2
 newObj.name = name; // step 3
 newObj.food = food;
 newObj.eat = eat;
 return newObj; // step 4
}
var cow = Animal("Cow","grass");
cow.eat();
var tiger = Animal("Tiger","meat");
tiger.eat();
console.log(cow instanceof Animal)// true

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

Это четыре правила, определяющие значение, которое будет привязано к «this» при вызове функции.

ПРИМЕЧАНИЕ.
Это моя первая статья в JS о моем понимании ключевого слова "this".
возможно, я что-то упустил здесь о "это ». Пожалуйста, не стесняйтесь исправлять меня, оставляя комментарии.