Переменный подъем

alert(myVar1);
return false;
var myVar1;

Выше кода выдает ошибку в IE, FF и Opera, утверждая, что оператор return должен прийти в функцию. Но это работает (показывает undefined) в Safari и Chrome.

Приведенный выше код был написан в глобальной области видимости. Снаружи все функции.

Какой-либо причине?

5 ответов

Решение

В javaScript переменные перемещаются в начало скрипта и затем запускаются. Поэтому, когда вы запустите это будет делать

var myVar1;
alert(myVar1);
return false;

Это потому, что у javascript нет истинного смысла лексической области видимости. Вот почему считается, что все переменные, объявленные в верхней части области, будут использоваться для предотвращения подъема, вызывающего проблему. JSLint будет стонать об этом.

Это хорошая статья, которая объясняет это http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

Возврат недействителен. Если вы хотите сделать настоящий пример подъема (взято по ссылке выше), сделайте

var foo = 1; 
function bar() { 
    if (!foo) { 
        var foo = 10; 
    } 
    alert(foo); 
} 
bar();

Это предупредит 10

РЕДАКТИРОВАТЬ ПОСЛЕ КОММЕНТАРИИ

Ниже мое понимание, и я где-то читал его, но не могу найти все источники, которые я прочитал, поэтому я открыт для исправления.

Это предупреждение благодаря различиям в JIT JavaScript. TraceMonkey ( http://ejohn.org/blog/tracemonkey/) Я полагаю, что возьму JavaScript и проведу быстрый статический анализ, а затем выполню JIT, а затем попробую запустить его. Если это не удается, то, очевидно, ничего не работает.

V8 не выполняет статический анализ и перемещается в JIT, затем что-то запускает. Это больше похоже на питона. Если вы запустите скрипт в консоли разработчика (ctrl+shift+j в windows) в Chrome, он выдаст ошибку, но также запустится, чтобы предупредить вас.

Иногда подъем объясняется таким образом, что это может создать неправильное впечатление, то есть переменные и функции поднимаются движком JavaScript, как если бы они были физически перемещены сверху, что на самом деле неправильно, как показано в приведенном ниже коде:

console.log(a);
var a = 'Hello World!';

То, что мы видим на консоли undefinedне 'Hello World'Итак, мы получили поведение следующего кода

var a;
console.log(a);
a = 'Hello World!';

не поведение

var a = 'Hello World!';
console.log(a);

что вы можете получить впечатление от объявления переменных и функций, перемещаемых в верхний оператор.

Но JavaScript на самом деле никуда не перемещает ваш код. Вы должны понимать контекст выполнения в JavaScript. Он имеет две фазы создания и выполнения. На этапе создания для этих переменных и функций создается пространство памяти, и люди, кажется, путают этот шаг с подъемом. JavaScript на самом деле никуда не перемещает ваш код, что происходит, если JavaScript создал пространство памяти для всего вашего кода, т. Е. Переменные и функции, функции могут быть полностью помещены в память, но в случае переменных присваивания обрабатываются на этапе выполнения контекста выполнения. Так что, когда вы делаете вар a = 'Hello World!'Движок JavaScript знает значение a когда он начинает выполнять его в фазе выполнения контекста выполнения, он помещает заполнитель в неопределенное значение, и все переменные первоначально устанавливаются в неопределенное в JavaScript. Так что не стоит полагаться на подъем и видеть неопределенное. Поэтому всегда полезно объявлять переменные и функции поверх вашего кода.

Раздел 12.9 (стр. 75) издания ECMA-262, издание 3, гласит:

Программа ECMAScript считается синтаксически некорректной, если она содержит return утверждение, которое не находится внутри FunctionBody.

Это return вне функции синтаксическая ошибка. Если возникает синтаксическая ошибка, код не запускается. Думайте о своем примере, как будто вы написали:

alert(myVar1);
return false;
syntax error))))))))))))))))));

Кроме того, в разделе 16 (стр. 157) говорится:

Реализация может обрабатывать любой экземпляр следующих видов ошибок времени выполнения как синтаксическую ошибку и, следовательно, сообщать об этом раньше:

  • Неправильное использование возврата, прерывания и продолжения.

Движок Firefox et. и др. (т.е. те реализации JavaScript, которые позволяют return в глобальном объеме) может соответствовать, предполагая, что следующий пункт (в том же разделе) позволяет определить реализацию return в глобальном масштабе:

Реализация должна сообщать обо всех ошибках, как указано, за исключением следующего:

  • Реализация может предоставлять дополнительные типы, значения, объекты, свойства и функции помимо тех, которые описаны в этой спецификации. Это может привести к тому, что конструкции (например, поиск переменной в глобальной области видимости) будут иметь поведение, определяемое реализацией, а не выдавать ошибку (например, ReferenceError).

Этот код имеет мало смысла:

  • var myVar1 никогда не побежит
  • return false; не вернет ничего, так как вы не в функции

Opera, IE и FF правы, чтобы выдать ошибку, потому что этот код действительно недействителен, так как вы не можете вернуться, если не находитесь в функции.

Если это работает в Safari и Chrome, то это должно быть потому, что движок javascript, который они используют, готов работать с ошибочным кодом. Я думаю, что они видятreturn"и бросьте или замените его каким-то break,

Более подробная информация о функциях: http://www.w3schools.com/js/js_functions.asp

Это вещь JavaScript Подъем, просто другими словами, мы пытаемся напечатать значение переменной, которая не содержит никакого значения

Javascript будет отображать вышеуказанный код как:-

var myVar1
alert (myVar1)
return false

Чтобы уточнить больше, я сослался на ссылку javascript hoisting: http://www.ufthelp.com/2014/11/JavaScript-Hoisting.html

Другие вопросы по тегам