Отслеживание того, на что ссылается this в функции JavaScript, может быть сложным и временами запутанным. Цель этой статьи — сделать это ключевое слово более понятным раз и навсегда, так что давайте начнем.

‘это’вне функции.

В контексте глобального выполнения this принимает значение глобального объекта ( globalв Node JS и окно в браузере).

var globalObject = this;
/*      Node js     */
globalObject === global; //true
/*      Browser     */
globalObject === window; //true

this внутри функции.

Значение thisвнутри функциизадается во время вызова функции с использованием любого из методов доступа к свойствам (' . ' или ' [ ] ').

  • Когда функция вызывается с помощью ‘ . ’, this устанавливается на соответствующий объект контекста.
  • Когда функция вызывается без использования оператора ' . ', this по умолчанию будет глобальным объектом (этот тип функции обычно называется «простой вызов»).

Теперь давайте попробуем несколько примеров, чтобы прояснить мою точку зрения.

  • Пример 1:
function f1() {
    return this;
}
var myObj = {
    method: f1
}
f1() === global; //true
myObj.method() === myObj; //true
  • Пример 2:
var myObj = {
    method: function() {
        return this;
    }
}
myObj.method() === myObj; //true
var f = myObj.method;
f() === global; //true

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

  • Пример 3:
function add(a, b, callback) {
    callback(a + b);
}
var myObj = {
    p: 1,
    q: 2,
    findSum: function() {
        add(this.p, this.q, function(sum) {
            console.log(sum);
            console.log(this === global);
        });
    }
};
myObj.findSum(); 
*/ prints the following output.
3
true
*/

Здесь обратный вызов вызывается простым вызовом, поэтому this по умолчанию будет глобальным. Поскольку это относится к каждому обратному вызову в JS, мы можем сделать вывод ..

Каждая функция обратного вызова имеет привязку this global, если иное this не задано явно .

Достаточно примеров, теперь мы посмотрим, как изменить это поведение по умолчанию…

вызвать() и применить():

Всякий раз, когда функция вызывается, она может привязываться к контексту по нашему выбору с помощью call() или apply().

function greetPerson (firstName, secondName) {
    var greetings = this.greet + ' ' + firstName + ' ' + secondName;
    console.log(greetings);
}
var obj1 = { greet: 'Hello' };
var obj2 = { greet: 'Ola' };
/* call({context}, param1, param2...) */
greetPerson.call(obj1, 'Pavan', 'Varma') // Hello Pavan Varma
greetPerson.call(obj2, 'Pavan', 'Varma') // Ola Pavan Varma
/* apply({context},[param1, param2...]) */
greetPerson.apply(obj1, ['Pavan', 'Varma']) // Hello Pavan Varma
greetPerson.apply(obj2, ['Pavan', 'Varma']) // Ola Pavan Varma

связать():

У каждой функции есть метод-прототипbind, который при вызове с каким-либо объектом создает новую копию этой функции, привязанную к этому объекту.

function greetPerson (firstName, secondName) {
    var greetings = this.greet + ' ' + firstName + ' ' + secondName;
    console.log(greetings);
}
var obj1 = { greet: 'Hello' };
var obj2 = { greet: 'Ola' };
/*       A new function bound to obj1     */
var greetPersonHello = greetPerson.bind(obj1);
greetPersonHello('Pavan', 'Varma');       // Hello Pavan Varma
greetPerson.call(obj2, 'Pavan', 'Varma'); // Ola Pavan Varma

JavaScript использует эти приемы за кулисами для реализации функций конструктора.

function Person(firstName, secondName) {
    this.firstName = firstName;
    this.secondName = secondName;
}
var p = new Person('Pavan', 'Varma');

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

Это все, что касается этого, удачного программирования (-_-).