this
this - объект-связка, который ссылается на контекст вызова функции. Или другими словами это ключевое слово, используется как указатель на тот объект, в контексте которого выполняется функция.
Самое главное что нужно помнить при работе с this: this не присваевается никакого значения до тех пор, пока функция не вызвана.
- Если вызвать как функцию
func(параметры); // this = window, если использовался строгий режим (use strick) - то this = undefined
- Если как метод
obj.func(); // this = obj obj['func'];
- Через метод apply/call
func.apply(obj, [param1, param2...]); // this = obj func.call(obj, param1, param2,...); // this = obj
- Конструктор
Конструктор работает следующим образом:var a = new func() // this = a, будет ссылатся на новый созданный объект
- созается новый пустой объект
- this получает ссылку на этом объект
- функция выполняется (может модифицировать this, например добавить новых свойств)
- возвращается this
Вот реализация собственного метода new:
function myNew(Const, args){
var thisValue = Object.create(Const.prototype);
var result = Const.apply(thisValue, args);
if(result !== null && typeof result === 'object'){
return result;
}
return thisValue;
}
А вВот еще более подробная таблица:
Когда использовать this следует наиболее осторожно
- при использование метода в качестве функции обратного вызова
- при замыкании
- при присваивании метода
- при заимствовании метода Также нужно помнить что функция теряет свой контекст, когда:
- возвращается как результат (
return
) - передается как аргумент
При использование метода в качестве функции обратного вызова
var user = {
name = 'Tom',
clickHander: function(event){
console.log(this.name);
}
}
element.onclick(user.clickHander); // this.name = undefined
Важно! при передачи функции (метода) как параметр другой функции - контекст вызова (this) теряется
Для исправления этой ситуации:
element.onclick(user.clickHandle.bind(user));
При замыкании
Важно! Замыкание не может получить доступ к значению this внешней функции
var user = {
hello: 'Hello',
data: [
{name: 'Tom'},
{name: 'Jerry'}
],
clickHandler: function(){
this.data.forEach(function(user){
console.log(this.hello + ' ' + user.name); //this = undefined
}
}
}
user.clickHandler();
Для исправления этой ситуации, нам нужно во внешней функции создать переменною и инициализировать ее this:
var user = {
hello: 'Hello',
data: [
{name: 'Tom'},
{name: 'Jerry'}
],
clickHandler: function(){
var self = this.hello; //!!!!
this.data.forEach(function(user){
console.log(self + ' ' + user.name); //!!!!
}
}
}
user.clickHandler();
При присвоеннии метода
var user = {
hello: 'Hello',
clickHandler: function(){
console.log(this.hello);
}
};
var hi = user.clickHandler;
hi(); // this = window, window.hello = undefined
Для исправления этой ситуации:
var hi = user.clickHandler.bind(user);
hi(); // this = user, user.hello = 'Hello'
При заимствовании метода
var user = {
name: 'Tom',
sayHi: function(){
console.log('Hi ' + this.name);
}
};
var admin = {
name: 'Jerry'
};
admin.sayHi = user.sayHi
Для исправления этой ситуации:
user.sayHi.apply(admin);
Материал взят из GetInstance - Ключевое слово this в JavaScript