Я пытаюсь понять лексическую область видимости ES6 (используя среду выполнения узла). Учтите следующее:
'use strict';
let x = 10;
function f() {
console.log(x);
console.log(y); // This should crash
}
let y = 5;
f();
Перефразируя книгу О'Рейли "Learning Javascript":
Лексическая область видимости означает, что любые переменные, находящиеся в области видимости, из которой вы определяете функцию (в отличие от того, когда вы ее вызываете), находятся в области видимости функции.
Однако, когда я запускаю эту программу (через узел), она выводит: 10 5
Разве здесь вызов console.log (y) не нарушает правила лексической области видимости? Если нет, то почему?
Изменить: для справки в будущем, похоже, что автор учебника (Learning Javascript 3rd Edition O'Reilly) недавно перечислил этот пример как ошибку в «Подтвержденных исправлениях». на http://www.oreilly.com/catalog/errata.csp?isbn=0636920035534
let
до его определения, вы получите ошибку временной мертвой зоны. Если вы поменяете местамиlet y = 5;
иf()
, вы получите сообщение об ошибке, а неundefined
в журнал. - person Benjamin Gruenbaum   schedule 16.04.2016f()
, то есть после инициализации переменной. - person Barmar   schedule 16.04.2016f
был, например, IIFE, код выбросил бы. Подъем - просто неправильный термин для этого. - person Benjamin Gruenbaum   schedule 16.04.2016var
поднятые операторы: это относится к операторам var и спискам формальных параметров некоторых нестрогих функций. - person Benjamin Gruenbaum   schedule 16.04.2016HoistableDeclaration
. В примечаниях он всегда рассматривает подъем как инициализированную привязку (примечания в 12.1.5, 13.7.5.9, 14.1.3, 14.4.2, 18.2.1.2 - также упоминаются конфликты подъема между var и let) - как для фактической спецификации (не примечания в спецификации) у нас естьHoistableDeclaration
, который является объявлением функции или объявлением генератора. Не похоже, что это действительно так однозначно, поскольку спецификация не фактически определяет подъем. - person Benjamin Gruenbaum   schedule 18.04.2016