31 lines
2.4 KiB
Markdown
31 lines
2.4 KiB
Markdown
<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` обычную функцию.
|
||
|