Ключевое слово this в javascript — учимся определять контекст на практике

в 19:22, , рубрики: javascript, jquery, this, метки: , ,

По просьбам некоторых читателей решил написать топик про контекст в javascript. Новички javascript часто не понимают значение ключевого слова this в javascript. Данный топик будет интересен не только новичкам, а также тем, кто просто хочет освежить данный аспект в памяти. Посмотрите пример ниже. Если вы затрудняетесь ответить на вопрос «что будет выведено в логе» хотя бы в одном из пунктов, или хотите просто посмотреть ответы — добро пожаловать под кат.

var f = function() {
    this.x = 5;
    (function() {
        this.x = 3;
    })();
    console.log(this.x);
};

var obj = {x: 4, m: function() {
    console.log(this.x);
}};


f();
new f();
obj.m();
new obj.m();
f.call(f);
obj.m.call(f);

Ответы, для нетерпеливых
3
5
4
undefined
5
5

В отличие от многих других языков программирования ключевое слово this в javascript не привязывается к объекту, а зависит от контекста вызова. Рассмотрим все варианты

1. Простой вызов функции

function f() {
    console.log(this === window); // true
}
f();

В данном случае this внутри функции f равен глобальному объекту (например, в браузере это window, в Node.js — global).
Самовызывающиеся функции (self-invoking) работают по точно такому же принципу.

(function () {
    console.log(this === window); // true
})();

2. В конструкторе

function f() {
    this.x = 5;
    console.log(this === window); // false
}
var o = new f();
console.log(o.x === 5); // true

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

3. В методе объекта

var o = {
    f: function() {
        return this;
    }
}
console.log(o.f() === o); // true

Если функция запускается как свойство объекта, то в this будет ссылка на этот объект. При этом не имеет значения откуда данная функция появилась в объекте, главное — как она вызывается, а именно какой объект стоит перед вызовом функции:

var o = {
    f: function() {
        return this;
    }
}
var o2 = {f: o.f};
console.log(o.f() === o);//true
console.log(o2.f() === o2);//true

Методы apply, call

Методы apply и call позволяют задать контекст для выполняемой функции. Разница между apply и call только в способе передачи параметров в функцию. Первый параметр обеих функций определяет контекст выполнения функции (то, чему будет равен this)

Разница в apply/call

function f(a,b,c) {
    return a * b + c;
}
f.call(f, 1, 2, 3); // аргументы перечисляются через запятую;
var args = [1,2,3];
f.apply(f, args); // // аргументы передаются в виде массива;
// В обоих случаях вызовется функция <b>f</b> с аргументами a = 1, b = 2, c = 3;

Автор: Sirian

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js