-
Notifications
You must be signed in to change notification settings - Fork 2
test page
Lesson 3 |
arguments • prototype • Контекст выполнения • Lexical Environment • hoisting • Область видимости • this • Контекст вызова
|
Занятие 3 |
|---|
![]() |
![]() |
![]() |
|---|
| • Функция является вызываемым объектом |
|---|
| • Функция, связанная с объектом через свойство, называется методом |
|---|
Как машина скорой помощи, функция может перемещаться от одного объекта к другому ( откуда она вызвана )
У функции
есть "контекст исполнения":
| свойства ( переменные ) | методы ( функции ) |
|---|---|
| комплект инструментов, медикаментов, перевязочных матералов, различные приборы ( капельницы, дефибриллятор, аппарат искусственного дыхания и т.д. ) | профессиональные навыки персонала машины скорой помощи ( могут сделать укол, поставить капельницу, применить дефибриллятор, перенести больного на носилках и т.д. ) |
Все это функция
возит с собой
В момент вызова у функции
появляется контекст вызова:
🏠 конкретные условия ( частный дом, квартира в многоэтажке, наличие или отсутствие лифта, водопровода и т.д. )
конкретный больной с конкретными симптомами, возрастом, историей болезни, характером и т.д.
![]() |
![]() |
![]() |
|---|
Контекст вызова - это объект
Обычно имя этого объекта стоит перед именем функции, и отделено от него точкой
Как правило, если имя объекта перед именем функции не указано, то контекстом вызова функции является глобальный объект window
Исключение составляют функции, контекст вызова которых установлен с помощью метода bind()
Отсюда следует, что все функции JS являются методами
Если объект ( "хозяин" метода ) не указан, подразумевается глобальный объект
1 |
|---|
Таким образом, функция - это "капсула" со своим содержимым
Содержимое "капсулы" недоступно из контекста вызова
( посторонние не могут использовать материалы, инструменты и аппараты
)
Ключевое слово this - это ссылка на объект, в контексте которого вызвана функция
Например, для функции 
this.адрес
this.этаж
this.квартира
this.больной.имя
this.больной.возраст
this.больной.симптомы
...Если бы не this, вряд ли функция могла бы помочь "больному" 
![]() |
![]() |
![]() |
|---|
Сигнатура функции - это ее имя + список формальных параметров
Формальные параметры функции - это имена переменных, перечисленные в круглых скобках при объявлении функции
Аргументами функции являются фактические значения, передаваемые функции при вызове
Если:
• функции будет передано аргументов больше числа формальных параметров, то лишние аргументы будут отброшены
• функции будет передано аргументов меньше числа формальных параметров, то недостающие аргументы получат значение undefined
![]() |
![]() |
![]() |
|---|
Функции JavaScript имеют встроенный объект arguments
У него есть свойство length, как у массива
Его элементы доступны по индексу, как и элементы массива
Однако это не массив
Поэтому к нему нельзя применить методы работы с массивами ( push, pop и т.д. )
Его можно преобразовать в обычный массив с помощью метода Array.from
var args = Array.from ( arguments )В объекте arguments находятся все аргументы, переданные функции при ее вызове
Они будут доступны по индексу строго в том порядке, в каком они были переданы функции при вызове
Например:
function testArguments () {
for ( var i = 0; i < arguments.length; i++ ) {
console.log ( `[ ${ ( i + " ]" ).padEnd ( 10 ) } ${ arguments [ i ] }` )
}
}
testArguments ( 27, false, "Fill", [ 7, 4, 5 ], null )![]() |
![]() |
![]() |
|---|
У объекта arguments есть свойство arguments.callee -
ссылка на выполняемую функцию ( функцию-"хозяина" объекта arguments )
function testArguments () {
console.log ( arguments.callee )
}
testArguments ( 5, false )В свойстве arguments.callee находится ссылка на саму функцию testArguments
2 |
3 |
4 |
5 |
|---|
![]() |
![]() |
![]() |
|---|
Когда происходит вызов функции, она активируется
Ей нужно где-то безопасно "разместить" свои данные, с которыми она будет работать
Кроме аргументов, которые она получит при вызове, у нее могут быть свои внутренние данные, которые нужны для временного хранения промежуточных результатов вычислений
Итак, у активной функции есть контекст выполнения, где разворачивается работа функции
Контекст выполнения создается каждый раз, когда происходит вызов функции
Что же будет в этом контексте?
При вызове функции создается объект, содержащий все необходимые переменные
Этот объект в спецификации языка называется LexicalEnvironment
В этом объекте будут храниться полученные аргументы и все переменные функции
поэтому его еще называют объектом переменных или объектом активации
Когда функция завершит работу, объект LexicalEnvironment будет удален из памяти
Однако функция может использовать какие-то переменные, которых нет в ее LexicalEnvironment
Они являются внешними, и находятся в другом контексте
Но они доступны функции
Функция "видит" их, поэтому они находятся в ее "области видимости"
Область видимости - важная часть контекста выполнения
Каждый вызов функции приводит к созданию нового контекста выполнения
Создание контекста выполнения происходит в два этапа:
сразу после вызова функции, но до начала выполнения кода
на этапе выполнения кода
При каждом возврате ( return ) происходит выход из контекста выполнения
Пока выполнение функции не завершено, ее контекст будет активным
Поскольку функции могут вызывать друг друга, их контекст помещается в стек
( очередь: последним пришел - первым ушел )
Верхним в этом стеке всегда будет текущий контекст исполнения

![]() |
![]() |
![]() |
|---|
Объект активации ( Lexical Environment ) содержит аргументы функции и все объявленные внутри функции переменные
( включая функции )
Таким образом, объект активации можно сравнить со шкафчиком для хранения "личных вещей" функции
Получить доступ к объекту активации невозможно
![]() |
![]() |
![]() |
|---|
После вызова функции:
В первую очередь формируется контекст исполнения:
- создается объект переменных ( или объект активации ),
- определяется область видимости
- устанавливается значение
this
Затем внутренним переменным присваиваются значения, код интерпретируется и выполняется
Обратите внимание на тот факт, что объявления всех внутренних переменных и вложенных функций происходит раньше, чем код начинает выполняться, независимо от порядка их появления в коде
А вот присвоение переменным значений происходит, когда код начинает выполняться
Это приводит к "поднятию" ( hoisting ) объявлений переменных и функций
1 |
2 |
|---|
![]() |
![]() |
|---|
Область видимости ( scope ) ограничивает действие идентификаторов переменных и функций
Представьте себе двух человек по имени Саша: 👨💼 парня и 🙎 девушку
Есть две комнаты, и парень Саша 👨💼 находится в первой комнате, а девушка Саша 🙎 - во второй
В каждой комнате есть наблюдатель
Если мы спросим наблюдателя из первой комнаты: "Кем является Саша?", то он ответит: "Парень" 👨💼
Зададим аналогичный вопрос наблюдателю из второй комнаты, и получим ответ: "Девушка" 🙎
Это происходит потому, что у каждой комнаты есть своя область видимости
Однако область видимости вложенных функций будет несколько иной
Предположим, что вложенные функции - коробки со стенками из тонированного стекла
Наши функции-коробки вложены одна в другую, как матрешки:
вторая коробка находится внутри первой,
третья - внутри второй, и так далее...
Наблюдатель в коробке 2 будет видеть не только содержимое коробки 2,
но и содержимое коробки 1
и комнаты, внутри которой находятся все коробки
но он не может увидеть содержимое коробки 3, хотя наблюдатель в коробке 3 его отлично видит...
как и наблюдателей во всех остальных коробках
и в комнате
Таким образом, если внутри функции будет обращение к переменной, то сначала функция будет искать эту переменную
в своем "шкафчике для личных вещей",
и если не найдет, то не постесняется "позаимствовать" эту переменную из внешнего шкафчика,
внутри которого она находится
Все доступные ей чужие "шкафчики" представляют собой цепочку областей видимости функции, которая является частью ее контекста выполнения
3 |
4 |
5 |
|---|
![]() |
![]() |
|---|
this - это еще одна составляющая контекста исполнения функции
this является ссылкой на контекст вызова функции
С помощью ключевого слова this можно получить доступ из функции ( или метода ) к свойствам объекта, в контексте которого была вызвана функция
function func () {
console.log ( this )
}при вызове функции func () в консоль будет выведен объект window
Внутри функции func () this указывает на объект window
function func () {
child ()
function child () {
console.log ( 'child this: ', this )
}
}
func () // window![]() |
![]() |
|---|
Если же функция является методом объекта, то ее контекстом вызова будет этот объект
var human = {
name: "Ivan",
say: function () {
console.log ( 'this: ', this )
}
}
human.say () // будет выведен объект humanТеперь посмотрим на функцию как на объект
function say () {
console.log ( 'function say: this: ', this )
}
function girl () {
console.log ( 'function girl: this: ', this )
}Добавим функции girl свойство say и вызовем функцию girl и ее свойство say:
girl.say = say
girl.say () // girl
girl () // window- Функцию как объект нельзя вывести с помощью метода
console.log - Для этой цели следует использовать метод
console.dir
function sample () {}
console.dir ( sample )В консоли мы получим следующую картинку:
▼ ƒ sample()
arguments: null
caller: null
length: 0
name: "sample"
▼ prototype:
► constructor: ƒ sample()
► __proto__: Object
► __proto__: ƒ ()
[[FunctionLocation]]: VM476:1
▼ [[Scopes]]: Scopes[1]
► 0: Global {type: "global", name: "", object: Window}
Обратите внимание на свойство prototype, которое есть только у функций
- это объект
- в этом объекте есть свойство
constructor - свойство
constructor- это ссылка на саму функцию sample()
Обратите также внимание на свойство __proto__, которое мы разберем далее
- это ссылка на объект, от которого функция унаследовала свои свойства и методы
- любая функция создается встроенным нативным объектом ( конструктором ) Function ()
- это свидетельствует о том, что функция - это объект
- свойство
constructorв__proto__- это ссылка на Function ()
• [[FunctionLocation]] и [[Scopes]] добавляет Chrome DevTools для целей отладки
![]() |
![]() |
|---|




КОНТЕКСТ ВЫЗОВА
3
w3schools
Упражнения
Всемирная паутина
Пример
