freeCodeCamp/guide/russian/javascript/this-reference/index.md

8.0 KiB
Raw Blame History

title localeTitle
this reference эта ссылка

this ссылка

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

Правило 1

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

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

Примечание. Если вы объявляете функцию foo() выше в строгом режиме, вы вызываете эту функцию в глобальной области, this будет undefined и присваивание this.a = 2 будет Uncaught TypeError исключение this.a = 2 .

Правило 2

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

function foo() { 
  this.a = 2; 
 } 
 
 var obj = { 
  foo: foo 
 }; 
 
 obj.foo(); 
 console.log(obj.a); // 2 

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

Правило 3

.call , .apply и .bind могут быть использованы на сайте вызова, чтобы явно привязать this . Использование .bind(this) - это то, что вы можете увидеть в довольно многих компонентах React.

var foo = function() { 
  console.log(this.bar) 
 } 
 
 foo.call({ bar: 1 }) // 1 

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

  • .call() : fn.call(thisObj, fnParam1, fnParam2)
  • .apply() : fn.apply(thisObj, [fnParam1, fnParam2])
  • .bind() : const newFn = fn.bind(thisObj, fnParam1, fnParam2)

Правило 4

function Point2D(x, y) { 
  this.x = x; 
  this.y = y; 
 } 
 
 var p1 = new Point2D(1, 2); 
 console.log(p1.x); // 1 
 console.log(p1.y); // 2 

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

Примечание. Когда вы вызываете функцию с new ключевым словом, мы также называем ее конструкторной функцией .

Правило 5

JavaScript определяет значение this во время выполнения, исходя из текущего контекста. Таким образом, this может иногда указывать на то, что вы ожидаете.

Рассмотрим этот пример класса Cat с методом под названием makeSound() , следуя шаблону в правиле 4 (выше) с помощью функции-конструктора и new ключевого слова.

var Cat = function(name, sound) { 
    this.name = name; 
    this.sound = sound; 
    this.makeSound = function() { 
        console.log( this.name + ' says: ' + this.sound ); 
    }; 
 } 
 var kitty = new Cat('Fat Daddy', 'Mrrooowww'); 
 kitty.makeSound(); // Fat Daddy says: Mrrooowww 

Теперь давайте попробуем дать кошке способ annoy() людей, повторяя его звук 100 раз, каждые полсекунды.

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

Это не работает, потому что внутри обратного вызова setInterval мы создали новый контекст с глобальной областью, поэтому this больше не указывает на наш экземпляр киски. В веб - браузере, this будет вместо этого указывать на объект Window, который не имеет makeSound() метод.

Несколько способов заставить его работать:

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

Другие источники