Из статьи MDN о строгом режиме:
Во-первых, строгий режим делает невозможным случайное создание глобальных переменных. В обычном JavaScript неправильный ввод переменной в присваивании создает новое свойство для глобального объекта и продолжает "работать" (хотя в будущем возможен сбой: вероятно, в современном JavaScript). Присвоения, которые случайно создали бы глобальные переменные, вместо этого выдают ошибку в строгом режиме:
'use strict'; // Assuming a global variable mistypedVariable exists mistypeVariable = 17; // this line throws a ReferenceError due to the // misspelling of variable
Что это значит? Движок обнаруживает, существует ли уже переменная с похожим именем (?!), или строгий режим просто запрещает объявлять глобальные переменные вне глобальной области видимости?
Вышеприведенная цитата, кажется, намекает на первую возможность, но это кажется... странным?
Комментарий в цитируемом коде вводит в заблуждение: часть "Предполагать" не имеет значения. Он должен действительно прочитать: "Если предположить, что ни одна глобальная переменная с точно таким именем не был определен с let
или var
,..."
Но обратите внимание, какова была цель фрагмента кода и комментария: показать, что в строгом режиме намного легче обнаружить орфографические ошибки. В небрежном режиме орфографическая ошибка останется незамеченной (без ошибок), и вы будете работать с двумя переменными, не зная об этом (по крайней мере, некоторое время)
По просьбе, я сделаю это в ответ :)
Я думаю, вы понимаете, что здесь уже происходит, и просто запутываетесь, читая эту цитату о "принятии глобальной переменной..." слишком буквально. (Я признаю, что это сформулировано таким образом, чтобы, возможно, привести к этой путанице.) Реальная ситуация очень проста и не имеет ничего общего с переменными, имеющими "похожие имена" (о которых JS не имеет понятия):
О чем говорят, так это о том, что произойдет, если вы присвоите значение переменной, которая не была официально объявлена (переменные объявляются с одним из ключевых слов var
, let
или const
). Не объявлять переменные - это плохая практика, и в строгом режиме выдает ошибку - это хорошо и предупреждает вас о вашей ошибке. Но в нестрогом режиме JS с радостью примет это и решит, что вы хотите объявить глобальную переменную с таким именем. Это почти никогда не то, что вы на самом деле хотите, загрязняет глобальное пространство имен, не сообщает вам о вашей ошибке и может привести к всевозможным хитрым ошибкам позже.
строгий режим просто запрещает объявлять глобальные переменные вне глобальной области видимости?
строгий режим определенно не запрещает объявлять глобальные переменные из любого места. В нестрогом режиме, если вы напишите:
someVar = 't';
он оценит:
window.someVar = 't';
(почему это происходит?) несмотря на запись внутри или вне области действия функции. на самом деле, строка была и объявлением, и оценкой переменной (посмотрите снова, у нее нет переменной var
поэтому она не должна ничего объявлять!).
Но это вызвало бы такой побочный эффект, который был не совсем хорош, и они ввели строгий режим, который, когда активен, наша первая строка выдаст ошибку. потому что это просто оценка без объявления этого в первую очередь.
Теперь, если вам нужно манипулировать глобальной областью действия внутри области действия функции, вы должны использовать только глобальный объект как ссылку:
var someGlobalVar;
var someOtherGlobalVar;
function hello() {
// this will make *someGlobalVar* to be redefined in the inner scope
// someGlobalVar != window.someGlobalVar
var someGlobalVar;
// manipulating inner variable, not global one
someGlobalVar = 's';
// it fine, you've accessed global object correctly
window.someGlobalVar = 's';
// you're still editing global object, because
// there no other variable inside of this scope having the same name
someOtherGlobalVar = 's';
}
Когда вы создаете глобальную переменную без этих ключевых слов: пусть const key объявляет для объекта windows и добавляется в глобальное пространство имен.
в строгом режиме вы не можете объявить переменную в глобальном пространстве имен и приклеить ее к объекту окна.
В языке программирования компилятора, таком как Java и C, вы не можете объявить переменную без определения ее типа. Строгий режим в JS поможет этому языку больше походить на язык компиляции.
mistypeVariable = 17;
правильное объявление Это было бы в неаккуратном режиме, но в строгом режиме это не создание переменных, поэтому, если у вас уже нет для негоlet
илиvar
, это ошибка.mistypeVariable
со значением 17, что почти всегда является гораздо менее полезным поведением. (Даже если этот глобал никогда не встанет у вас на пути, чего, вероятно, не будет, вы не узнаете об ошибке до тех пор, пока не попытаетесь выяснить какую-то странную ошибку.)