В JavaScript это ключевое слово относится к объекту, которому оно принадлежит.

Само по себе это относится к глобальному объекту.

В функции это относится к глобальному объекту.

В методе это относится к объекту-владельцу.

В функции в строгом режиме это не определено.

В событии это относится к элементу, который получил событие.

Глобальный контекст:

это окно === // возвращает true;

this === globalThis // возвращает true

Создайте глобальную переменную с именем «ключ». Создайте простую функцию с именем «печать».

var key = “value”
function print() {
    console.log(this.key)
}
print() // outputs "value"

Внутри функции:

this относится к глобальному объекту внутри функции.

Попробуйте запустить эту программу на вашей консоли:

var v = “okay”
function make() {
   this.v = “bye”;
   console.log(v)
}
v = “now”
console.log(v) // outputs “now”

Это потому, что вы еще не вызвали функцию make(). Если вы вызовете функцию make(), а затем напечатаете v. Будет выведено «до свидания». это указывает на глобальный объект внутри функции.

var v = “okay”
function make() {
   this.v = “bye”;
   console.log(v)
}
v = “now”
make()
console.log(v) // outputs “bye”

Вызов функции «make()» напрямую, а не для объекта, такого как obj.abc() — рассматривает окно как вызываемый объект, если функция вызывается напрямую. Следовательно, он имеет доступ к глобальным объектам.

Иногда мы теряем ссылку на «это». Когда это происходит, мы заканчиваем тем, что используем сбивающие с толку хаки, чтобы сохранить нашу ссылку на этот

Сохранение этой ссылки в функциях:

Пример, когда мы теряем ссылку this:

var module = {
  xx: 42,
  getX: function() {
   return this.xx;
  }
};
var unboundGet = module.getX;
console.log(unboundGet()); // outputs undefined

Почему ? — Потому что, когда вы вызываете функцию unboundGet(), она вызывается для глобального объекта, а глобально не существует переменной с именем xx.

Следовательно, нам нужно найти способ передать ссылку this в эти функции. Вот где на сцену выходят call(), apply() и bind().

  1. связать()

Метод bind() создает новую функцию, которая при вызове имеет ключевое слово this, установленное на предоставленный объект. Преимущество в том, что этот метод можно использовать и позже, в любой другой части кода.

var module = {
  x: 42,
  getX: function() {
    return this.x;
  }
};
car boundGet = unboundGet.bind(module); //to bind an object
console.log(boundGet()); // outputs 42

2. вызов()

Метод call() вызывает функцию с заданным контекстом this и аргументами, предоставленными индивидуально.

Метод вызывается немедленно и позволяет передавать больше параметров, чем только контекст this.

Пример: yourFuntion.call(thisReference, 'vvk', mayer')

3. применить()

call() и apply() похожи. Единственная разница в том, что apply() ожидает, что все параметры будут в массиве, кроме объекта, который действует как «этот» контекст. call() ожидает, что все параметры будут переданы по отдельности (определенно не в виде массива)

Пример: yourFuntion.apply(thisReference,['vvk', mayer'])

Контекст класса:

class Car {
  constructor() {
    //Bind sayBye but not sayHi to show the difference
    this.sayBye = this.sayBye.bind(this);
  }
  sayHi() {
     console.log(`Hello from ${this.name}`);
  }
  sayBye() {
    console.log(`Bye from ${this.name}`);
  }
  get name() {
    return ‘Ferrari’;
  }
}
class Bird {
  get name() {
    return ‘Tweety’;
  }
}
const car = new Car();
const bird = new Bird();
// The value of ‘this’ in methods depends on their caller
car.sayHi(); // Hello from Ferrari
bird.sayHi = car.sayHi;
bird.sayHi(); // Hello from Tweety
// For bound methods, ‘this’ doesn’t depend on the caller
car.sayBye();
bird.sayBye = car.sayBye;
bird.sayBye(); // Bye from Ferrari
Output :
  Hello from Ferrari
  Hello from Tweety
  Bye from Ferrari
  Bye from Ferrari

Обратите внимание на последние три оператора в приведенной выше программе.
И car.sayBye(), и bird.sayBye() имеют одинаковый результат. Это связано с тем, что внутри конструктора вы установили контекст this для метода sayBye с помощью bind(). Следовательно, даже если вы вызываете sayBye() для разных объектов, это не имеет значения, поскольку вы уже использовали bind() и определили контекст this.

Функции со стрелками:

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

Лексическая область видимости в JavaScript означает, что переменная, определенная вне функции, может быть доступна внутри другой определенной функции. Но обратное неверно; переменные, определенные внутри функции, не будут доступны вне этой функции.

var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject); // true
var Actor = {
  name: ‘RajiniKanth’,
  movies: [‘Kabali’, ‘Sivaji’, ‘Baba’],
  showMovies: function() {
  console.log(this.name)
  this.movies.forEach(function(movie) {
    console.log(this.name + “ has acted in “ + movie);
  });
  }
}
Actor.showMovies();
Output :
  RajiniKanth
  has acted in Kabali
  has acted in Sivaji
  has acted in Baba

Имя (выделенное полужирным шрифтом) не печатается внутри цикла forEach — поскольку это относится к глобальному объекту внутри forEach, нам нужно установить этот контекст вне forEach, чтобы логика могла работать правильно.

var Actor = {
 name: ‘RajiniKanth’,
 movies: [‘Kabali’, ‘Sivaji’, ‘Baba’],
 showMovies: function() {
 console.log(this.name)
 var obj = this;
 this.movies.forEach(function(movie) {
  console.log(obj.name + “ has acted in “ + movie);
  });
 }
};
Actor.showMovies();
Output :
RajiniKanth
RajiniKanth has acted in Kabali
RajiniKanth has acted in Sivaji
RajiniKanth has acted in Baba

Та же логика прекрасно работает с использованием функции стрелки без явной установки контекста this.

var Actor = {
 name: ‘RajiniKanth’,
 movies: [‘Kabali’, ‘Sivaji’, ‘Baba’],
 showMovies: function() {
 this.movies.forEach((movie) => {
  console.log(this.name + “ has acted in “ + movie);
 });
}
};
Output :
  RajiniKanth has acted in Kabali
  RajiniKanth has acted in Sivaji
  RajiniKanth has acted in Baba

С функциями стрелки this привязывается к объемлющей области во время создания и не может быть изменено. Новый оператор, bind, call и apply на это не влияют.

Как метод объекта:

Когда функция вызывается как метод объекта, ее «это» устанавливается на объект, для которого вызывается метод.

var test = {
 key: 37,
 f: function() {
  return this.key;
 }
};
console.log(test.f()); // 37

Как обработчик событий DOM:

В обработчиках событий HTML «это» относится к элементу HTML, который получил событие.

<button onclick=”this.style.display=’none’”>Click to Remove Me!</button>

Если вы выполните вышеуказанное выражение и нажмете на кнопку, кнопка будет удалена.