Рубрики
Без рубрики

Полное руководство по этому в JavaScript

В JavaScript каждая функция имеет эту ссылку, созданную автоматически, когда вы объявляете его. JavaScript Это очень похоже на эту ссылку на других языках на основе классовых классовых, таких как Java или C # (JavaScript – это язык на основе прототипа и понятие «класс»): он указывает на то, какой объект вызывает

Автор оригинала: FreeCodeCamp Community Member.

В JavaScript каждая функция имеет это Ссылка автоматически создана, когда вы объявляете его.

JavaScript’s это очень похоже на это Ссылка на других классовых языках, таких как Java или C # (JavaScript – это прототип на основе языка и понятие «класс»): Это указывает на то, какой объект звонит на функцию (Этот объект иногда называют контекст ). В JavaScript, однако, это Ссыловые внутренние функции могут быть связаны с разными объектами в зависимости от того, где называется функция Отказ

Вот 5 основных правил для это Привязка в JavaScript:

Правило 1.

Когда функция называется в глобальном объеме, это Ссылка по умолчанию связана с Глобальный объект ( Окно в браузере или Global в Node.js). Например:

function foo() {
  this.a = 2;
}

foo();
console.log(a); // 2

Примечание: если вы объявите foo () Функция выше в строгом режиме, то вы называете эту функцию в глобальном объеме, это будет undefined и задание Это бросит Неуправляемая типография исключение.

Правило 2.

Давайте рассмотрим пример ниже:

function foo() {
  this.a = 2;
}

const obj = {
  foo: foo
};

obj.foo();
console.log(obj.a); // 2

Очевидно, в приведенном выше фрагменте foo () Функция называется контекст это obj объект и это Ссылка сейчас связана с obj Отказ Поэтому, когда функция называется с объектом контекста, это Ссылка будет связана с этим объектом.

Правило 3.

.call , .apply и .bind Все можно использовать на вызове, чтобы явно привязать это Отказ Использование .bind (это) Это то, что вы можете видеть в довольно много компонентов реагирования.

const foo = function() {
  console.log(this.bar)
}

foo.call({ bar: 1 }) // 1

Вот быстрый пример того, как каждый используется для привязки это :

  • .call () : fn.call (ithobj, fnparam1, fnparam2)
  • .apply () : fn.apply (ithobj, [fnparam1, fnparam2]))
  • .bind () : const.bind (ithobj, fnparam1, fnparam2)

Правило 4.

function Point2D(x, y) {
  this.x = x;
  this.y = y;
}

const p1 = new Point2D(1, 2);
console.log(p1.x); // 1
console.log(p1.y); // 2

То, что вы должны заметить, что это Point2D Функция вызывается с Новый ключевое слово и это Ссылка связана с P1 объект. Поэтому, когда функция называется с Новый Ключевое слово, это создаст новый объект и это Ссылка будет связана с этим объектом.

Примечание. Как вы называете функцию с Новый Ключевое слово, мы также называем это как Функция конструктора Отказ

Правило 5.

JavaScript определяет значение это во время выполнения на основе текущего контекста. Итак, это иногда может указать на что-то другое, чем то, что вы ожидаете.

Рассмотрим этот пример класса Cat с методом, называемым Издан () После шаблона в правиле 4 (выше) с функцией конструктора и Новый ключевое слово.

const Cat = function(name, sound) {
  this.name = name;
  this.sound = sound;
  this.makeSound = function() {
    console.log( this.name + ' says: ' + this.sound );
  };
}

const kitty = new Cat('Fat Daddy', 'Mrrooowww');
kitty.makeSound(); // Fat Daddy says: Mrrooowww

Теперь давайте постараемся дать коту путь к Annoy () Люди, повторяя его звук 100 раз, один раз в полторы.

const Cat = function(name, sound) {
  this.name = name;
  this.sound = sound;
  this.makeSound = function() {
    console.log( this.name + ' says: ' + this.sound );
  };
  this.annoy = function() {
    let count = 0, max = 100;
    const t = setInterval(function() {
      this.makeSound(); // <-- this line fails with `this.makeSound is not a function` 
      count++;
      if (count === max) {
        clearTimeout(t);
      }
    }, 500);
  };
}

const kitty = new Cat('Fat Daddy', 'Mrrooowww');
kitty.annoy();

Это не работает, потому что внутри Setinterval Обратный вызов Мы создали новый контекст с глобальным объемом, поэтому это больше не указывает на наш хитрый экземпляр. В веб-браузере это вместо этого укажет окно объекта, который не имеет Издан () метод.

Пара способов сделать это работать:

  1. Перед созданием нового контекста назначить это к локальной переменную, названной я или Я или все, что вы хотите назвать это, и используйте эту переменную внутри обратного вызова.
const Cat = function(name, sound) {
  this.name = name;
  this.sound = sound;
  this.makeSound = function() {
    console.log( this.name + ' says: ' + this.sound );
  };
  this.annoy = function() {
    let count = 0, max = 100;
    const self = this;
    const t = setInterval(function() {
      self.makeSound();
      count++;
      if (count === max) {
        clearTimeout(t);
      }
    }, 500);
  };
}

const kitty = new Cat('Fat Daddy', 'Mrrooowww');
kitty.annoy();
  1. С ES6 вы можете избежать назначения это к локальной переменной, используя функцию стрелки, которая связывается это в контекст окружающего кода, где он определяется.
const Cat = function(name, sound) {
  this.name = name;
  this.sound = sound;
  this.makeSound = function() {
    console.log( this.name + ' says: ' + this.sound );
  };
  this.annoy = function() {
    let count = 0, max = 100;
    const t = setInterval(() => {
      this.makeSound();
      count++;
      if (count === max) {
        clearTimeout(t);
      }
    }, 500);
  };
}

const kitty = new Cat('Fat Daddy', 'Mrrooowww');
kitty.annoy();