en.javascript.info/1-js/6-objects-more/1-object-methods/3-why-this/solution.md
Ilya Kantor 87bf53d076 update
2014-11-16 01:40:20 +03:00

31 lines
2.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<ol>
<li>Обычный вызов функции в контексте объекта.</li>
<li>То же самое, скобки ни на что не влияют.</li>
<li>Здесь не просто вызов `obj.method()`, а более сложный вызов вида `(выражение).method()`. Такой вызов работает, как если бы он был разбит на две строки:
```js
f = obj.go; // сначала вычислить выражение
f(); // потом вызвать то, что получилось
```
При этом `f()` выполняется как обычная функция, без передачи `this`.
</li>
<li>Здесь также слева от точки находится выражение, вызов аналогичен двум строкам.</li>
</ol>
В спецификации это объясняется при помощи специального внутреннего типа [Reference Type](http://es5.github.com/x8.html#x8.7).
Если подробнее -- то `obj.go()` состоит из двух операций:
<ol>
<li>Сначала получить свойство `obj.go`.</li>
<li>Потом вызвать его как функцию.</li>
</ol>
Но откуда на шаге 2 получить `this`? Как раз для этого операция получения свойства `obj.go` возвращает значение особого типа `Reference Type`, который в дополнение к свойству `go` содержит информацию об `obj`. Далее, на втором шаге, вызов его при помощи скобок `()` правильно устанавливает `this`.
**Любые другие операции, кроме вызова, превращают `Reference Type` в обычный тип, в данном случае -- функцию `go` (так уж этот тип устроен).**
Поэтому получается, что `(method = obj.go)` присваивает в переменную `method` функцию `go`, уже без всякой информации об объекте `obj`.
Аналогичная ситуация и в случае `(4)`: оператор ИЛИ `||` делает из `Reference Type` обычную функцию.