Поднятие переменной (hoisting) — КиберПедия 

Поперечные профили набережных и береговой полосы: На городских территориях берегоукрепление проектируют с учетом технических и экономических требований, но особое значение придают эстетическим...

Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...

Поднятие переменной (hoisting)

2020-10-20 115
Поднятие переменной (hoisting) 0.00 из 5.00 0 оценок
Заказать работу

Где бы ни появлялось var внутри области видимости, это объявление принадлежит всей области видимости и доступно в любом месте внутри области.

Метафорически это поведение называется поднятие (hoisting), когда объявление var концептуально "перемещается" на вершину своей объемлющей области видимости. Технически этот процесс более точно объясняется тем, как компилируется код, но сейчас опустим эти подробности.

Пример:

var a = 2; foo();                                 // работает, так как определение `foo()`                                               // "всплыло" function foo() {    a = 3;     console.log(a); // 3     var a;                        // определение "всплыло"                                               // наверх `foo()`} console.log(a); // 2

Предупреждение: Не общепринято и не так уж здраво полагаться на поднятие переменной, чтобы использовать переменную раньше в ее области видимости, чем появится ее объявление с var: такое может сбить с толку. Общепринято и приемлемо использовать всплытие объявлений функций, что мы и делали с вызовом foo(), появившемся до ее объявления.

Вложенные области видимости

Когда вы объявляете переменную, она доступна везде в ее области видимости, так же как и в более нижних/внутренних областях видимости. Например:

function foo() {    var a = 1;     function bar() {            var b = 2;             function baz() {                     var c = 3;                      console.log(a, b, c); // 1 2 3            }             baz();            console.log(a, b);          // 1 2    }     bar();    console.log(a);                      // 1} foo();

Заметьте, что c не доступна внутри bar(), потому что она объявлена только внутри внутренней области видимости baz() и b не доступна в foo() по той же причине.

Если вы попытаетесь получить доступ к значению переменной в области видимости, где она уже недоступна, вы получите ReferenceError. Если вы попытаетесь установить значение переменной, которая еще не объявлена, все либо закончится тем, что переменная создастся в самой верхней глобальной области видимости (плохо!), либо получите ошибку в зависимости от "строгого режима" (см. "Строгий режим"). Давайте взглянем:

function foo() {    a = 1; // `a` формально не объявлена} foo();a;                   // 1 — упс, автоматическая глобальная переменная:(

Это очень плохая практика. Не делайте так! Всегда явно объявляйте свои переменные.

В дополнение к созданию объявлений переменных на уровне функций, ES6 позволяет вам объявлять переменные, принадлежащие отдельным блокам (пара {.. }), используя ключевое слово let. Кроме некоторых едва уловимых деталей, правила области видимости будут вести себя точно так же, как мы видели в функциях:

function foo() {    var a = 1;     if (a >= 1) {            let b = 2;             while (b < 5) {                     let c = b * 2;                     b++;                      console.log(a + c);            }    }} foo();// 5 7 9

Из-за использования let вместо var, b будет принадлежать только оператору if и следовательно не всей области видимости функции foo(). Точно так же c принадлежит только циклу while. Блочная область видимости очень полезна для управления областями ваших переменных более точно, что может сделать ваш код более легким в обслуживании в долгосрочной перспективе.

Примечание: Более детальная информация об области видимости есть в книге Область видимости и замыкания этой серии. См. книгу ES6 и за его пределами этой серии, чтобы узнать больше о блочной области видимости let.

Условные операторы

В дополнение к оператору if, который мы кратко представили в главе 1, JavaScript предоставляет несколько других механизмов условных операторов, на которые нам следует взглянуть.

Иногда вы ловите себя на том, что пишете серию операторов if..else..if примерно как тут:

if (a == 2) {    // сделать что-то}else if (a == 10) {    // сделать что-то еще}else if (a == 42) {    // сделать еще одну вещь}else {    // резервный вариант}

Эта структура работает, но она слишком подробна, поскольку вам нужно указать проверку для a в каждом случае. Вот альтернативная возможность, оператор switch:

switch (a) {    case 2: // сделать что-то            break;    case 10: // сделать что-то еще            break;    case 42: // сделать еще одну вещь            break;    default: // резервный вариант}

Оператор break важен, если вы хотите, чтобы выполнились операторы только одного case. Если вы опустите break в case и этот case подойдет или выполнится, выполнение продолжится в следующем операторе case независимо то того, подходит ли этот case. Этот так называемый "провал (fall through)" иногда полезен/желателен:

switch (a) {    case 2:    case 10:            // какие-то крутые вещи            break;    case 42:            // другие вещи            break;    default:            // резерв}

Здесь если a будет либо 2, либо 10, то выполнятся операторы "какие-то крутые вещи".

Еще одна форма условного оператора в JavaScript — это "условная операция", часто называемая "тернарная операция". Это примерно как более краткая форма отдельного оператора if..else. Например:

var a = 42; var b = (a > 41)? "hello": "world"; // эквивалентно этому: // if (a > 41) {// b = "hello";// }// else {// b = "world";// }

Если проверяемое выражение (здесь a > 41) вычисляется как true, результатом будет первая часть ("hello"), в противном случае результатом будет вторая часть ("world"), а затем независимо от результата он будет присвоен переменной b.

Условная операция не обязательно должна использоваться в присваивании, но это самое распространенное ее использование.

Примечание: Более детальная информация об условиях проверки и других шаблонах для switch и?: есть в книге Типы и синтаксис этой серии.

Строгий режим (Strict Mode)

ES5 добавила "строгий режим" в язык, который ужесточил правила для определенных сценариев. В общем-то, эти ограничения выглядят как большее соответствие кода более безопасному и более подходящему набору рекомендаций. Также, тяготение к строгому режиму сделает ваш код более оптимизируемым движком. Строгий режим — это большая победа для кода и вам следует использовать его во всех своих программах.

Вы можете явно указать его для отдельной функции или целого файла, в зависимости от того, где вы разместите директиву строго режима:

function foo() {    "use strict";     // этот код в строгом режиме     function bar() {            // этот код в строгом режиме    }} // этот код в нестрогом режиме

Сравните с:

"use strict"; function foo() {    // этот код в строгом режиме     function bar() {            // этот код в строгом режиме    }} // этот код в строгом режиме

Всего одно ключевое отличие (улучшение!) строго режима — запрет автоматического неявного объявления глобальных переменных из-за пропускаvar:

function foo() {    "use strict"; // включить строгий режим    a = 1;               // `var` missing, ReferenceError} foo();

Если вы включаете строгий режим в своем коде и получаете ошибки, или код начинает вести себя ошибочно, у вас может возникнуть соблазн избегать строго режима. Но потворствовать этому инстинкту — плохая идея. Если строгий режим является причиной проблем в вашей программе, почти определенно это знак того, что в вашей программе есть вещи, которые надо исправить.

Строгий режим не только способствует безопасности вашего кода и делает ваш код более оптимизируемым, но и заодно показывает будущее направление языка. Вам будет легче привыкнуть к строгому режиму сейчас, чем продолжать откладывать его в сторону — потом код будет сложнее сконвертировать!

Примечание: Более детальная информация о строгом режиме есть в главе 5 книги Типы и синтаксис этой серии.

Функции как значения

До сих пор мы обсуждали функции как основной механизм области видимости в JavaScript. Вспомните синтаксис типичного объявления функции, указанный ниже:

function foo() {    //..}

Хотя это может показаться очевидным из синтаксиса, foo — по сути просто переменная во внешней окружающей области видимости, у которой есть ссылка на объявляемую функцию. То есть, функция сама является значением, так же как 42 или [1,2,3].

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

В связи с этим, о значении-функции следует думать как о выражении, сродни любому другому значению или выражению.

Пример:

var foo = function() {    //..}; var x = function bar(){    //..};

Первое функциональное выражение, присваиваемое переменной foo, называется анонимным поскольку у него нет имени.

Второе функциональное выражение именованное (bar), несмотря на то, что является ссылкой, также присваивается переменной x. Выражения с именованными функциями как правило более предпочтительны, хотя выражения с анонимными функциями все еще чрезвычайно употребительны.

Более детальная информация есть в книге Область видимости и замыкания этой серии.


Поделиться с друзьями:

Наброски и зарисовки растений, плодов, цветов: Освоить конструктивное построение структуры дерева через зарисовки отдельных деревьев, группы деревьев...

Автоматическое растормаживание колес: Тормозные устройства колес предназначены для уменьше­ния длины пробега и улучшения маневрирования ВС при...

Кормораздатчик мобильный электрифицированный: схема и процесс работы устройства...

Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.01 с.