Реальный ответ на этот вопрос будет около 3 страниц. Но я стараюсь сделать это как можно короче. ECMA- / Javascript это все о Execution Contexts
и Object
. В ECMAscript есть три основных типа контекста: Global context
, Function contexts
и eval contexts
.
Каждый раз, когда вы вызываете функцию, ваш движок порождает ее в своем собственном function context
. Кроме того, существует такой объект, который называется Activation object
. Этот мистический объект является частью function context
, который состоит как минимум из:
- [[Scope chain]]
- Объект активации
- значение контекста "this"
Может быть больше свойств на разных движках, но эти три требуются для любой реализации ES. Однако вернемся к теме. Если вызывается контекст функции, все parent contexts
(или, точнее, Activation objects
из родительского контекста) копируются в свойство [[Scope]]
. Вы можете думать об этом свойстве как о массиве, который содержит (Activation-) Objects. Теперь любая относящаяся к функции информация хранится в объекте активации (формальные параметры, переменные, объявления функций).
В вашем примере переменная digits
хранится в объекте активации для namenew
. Второй, когда создается внутренняя анонимная функция, она добавляет это Activation object
в свои свойства [[Scope]]
. Когда вы вызываете digits[n]
там, Javascript сначала пытается найти эту переменную в своем собственном объекте активации. Если это не удается, поиск переходит в Scopechain. И вуаля, там мы нашли переменную, потому что мы скопировали АО из внешней функции.
Я уже написал слишком много для короткого ответа, но чтобы действительно дать хороший ответ на такой вопрос, вам нужно объяснить некоторые базовые знания об ES здесь. Полагаю, этого достаточно, чтобы дать вам представление о том, что на самом деле происходит «под капотом» (еще многое нужно знать, если вы хотите больше читать, я дам вам несколько ссылок).
Вы просили об этом, вы получаете это:
http://dmitrysoshnikov.com/ecmascript/javascript-the-core/