Это фундаментальное проектное решение, восходящее к первому определению языка JavaScript.
Рассмотрим объект
var myObjet = {
someValue: 0,
someFunction: function() {
return this.someValue;
}
};
Теперь, когда вы пишете
var myValue = myObject.someValue;
Вы получаете именно то, что вложили в него, как если бы вы написали
var myValue = 0;
Подобным образом, когда вы пишете
var myFunction = myObject.someValue;
Вы получаете именно то, что вложили в него,как если бы вы написали
var myFunction = (function() {
return this.someValue;
});
... за исключением того, что вы больше не находитесь в объекте.Так что this
ничего не значит.Действительно, если вы попробуете
console.log(myFunction());
, вы увидите
undefined
точно так же, как если бы вы написали
console.log(this.someValue);
вне любого объекта.
Итак, что такое this
?Итак, JavaScript решает это следующим образом:
- Если вы пишете
myObject.myFunction()
, то при выполнении части myFunction()
this
равно myObject
. - Если вы простонапишите
myFunction()
, тогда this
- текущий глобальный объект, который обычно равен window
(не всегда, есть много особых случаев). - Ряд функций может вставлять
this
в другойфункция (например, call
, apply
, map
, ...)
Теперь, почему это происходит?Ответ в том, что это необходимо для прототипов.Действительно, если вы теперь определите
var myDerivedObject = Object.create(myObject);
myDerivedObjet.someValue = 42;
, у вас теперь есть объект, основанный на myObject
, но с другим свойством someValue
console.log(myObject.someFunction()); // Shows 0
console.log(myDerivedObject.someFunction()); // Shows 42
Это потому, что myObject.someFunction()
использует myObject
для this
, тогда как myDerivedObject.someFunction()
использует myDerivedObject
для this
.
Если бы this
было захвачено во время определения someFunction
, мы получили бы 0
в обоихлиний, но это также сделало бы прототипы гораздо менее полезными.