По просьбам некоторых читателей решил написать топик про контекст в 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);
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)
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