function из - Какова область видимости переменных в JavaScript?




замыкания статические (22)

ES5 и ранее:

Переменные в Javascript были первоначально (pre ES6) лексически функционируют в области видимости. Термин лексически ограниченный означает, что вы можете увидеть область действия переменных, «глядя» на код.

Каждая переменная, объявленная с varключевым словом, привязана к функции. Однако, если другая функция объявлена ​​внутри этой функции, эти функции будут иметь доступ к переменным внешних функций. Это называется цепочкой областей видимости . Он работает следующим образом:

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

Пример:

// global scope
var foo = 'global';
var bar = 'global';
var foobar = 'global';

function outerFunc () {
 // outerFunc scope
 var foo = 'outerFunc';
 var foobar = 'outerFunc';
 innerFunc();
 
 function innerFunc(){
 // innerFunc scope
  var foo = 'innerFunc';
  console.log(foo);
  console.log(bar);
  console.log(foobar);
  }
}

outerFunc();

Что происходит , когда мы пытаемся войти переменные foo, barи foobarв консоли следующее:

  1. Мы пытаемся записать foo на консоль, foo можно найти внутри самой функции innerFunc. Следовательно, значение foo разрешено для строки innerFunc.
  2. Мы пытаемся подключить бранд к консоли, панель не может быть найдена внутри самой функции innerFunc. Поэтому нам нужно подняться по цепочке видимости . Сначала мы рассмотрим внешнюю функцию, в которой innerFuncбыла определена функция . Это функция outerFunc. В рамках outerFuncмы можем найти переменную строку, содержащую строку 'outerFunc'.
  3. foobar не может быть найден в innerFunc. ,Поэтому нам нужно забрать цепочку областей видимости в область innerFunc. Здесь также не может быть найдено, мы поднимаемся на другой уровень в глобальную область (то есть самый внешний охват). Здесь мы находим переменную foobar, которая содержит строку «global». Если бы он не нашел переменную после подъема цепочки областей, JS-движок запустил бы referenceError .

ES6 (ES 2015) и старше:

Те же концепции лексического охвата и scopechain все еще применяются ES6. Однако были введены новые способы объявления переменных. Есть следующее:

  • let : создает переменную область с областью
  • const : создает переменную области, которая должна быть инициализирована и не может быть переназначена

Самое большое различие между ними varи let/ constесть то, что varобласть действия ограничена, тогда как let/ constявляются блочными областями. Вот пример, чтобы проиллюстрировать это:

let letVar = 'global';
var varVar = 'global';

function foo () {
  
  if (true) {
    // this variable declared with let is scoped to the if block, block scoped
    let letVar = 5;
    // this variable declared with let is scoped to the function block, function scoped
    var varVar = 10;
  }
  
  console.log(letVar);
  console.log(varVar);
}


foo();

В приведенном выше примере letVar регистрирует значение global, поскольку объявленные переменные letявляются блочными. Они перестают существовать вне их соответствующего блока, поэтому к переменной не может быть доступа вне блока if.

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


Старая школа JavaScript

Традиционно, JavaScript действительно имеет только два типа области:

  1. Глобальная область : переменные известны во всем приложении, начиная с начала приложения (*)
  2. Функциональная область : переменные известны внутри функции, в которой они объявлены, начиная с начала функции (*)

Я не буду подробно останавливаться на этом, потому что уже есть много других ответов, объясняющих разницу.

Современный JavaScript

Самые последние спецификации JavaScript теперь также позволяют использовать третью область:

  1. Область блока : переменные известны в блоке, в котором они объявлены, с момента их объявления вперед (**)

Как создать переменные области блока?

Традиционно вы создаете свои переменные следующим образом:

var myVariable = "Some text";

Переменные области блока создаются следующим образом:

let myVariable = "Some text";

Итак, какова разница между функциональной областью и объемом блока?

Чтобы понять разницу между функциональной областью и объемом блока, рассмотрите следующий код:

// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here

function loop(arr) {
    // i IS known here, but undefined
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here

    for( var i = 0; i < arr.length; i++ ) {
        // i IS known here, and has a value
        // j IS NOT known here
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    };

    // i IS known here, and has a value
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here

    for( let j = 0; j < arr.length; j++ ) {
        // i IS known here, and has a value
        // j IS known here, and has a value
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    };

    // i IS known here, and has a value
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here
}

loop([1,2,3,4]);

for( var k = 0; k < arr.length; k++ ) {
    // i IS NOT known here
    // j IS NOT known here
    // k IS known here, and has a value
    // l IS NOT known here
};

for( let l = 0; l < arr.length; l++ ) {
    // i IS NOT known here
    // j IS NOT known here
    // k IS known here, and has a value
    // l IS known here, and has a value
};

loop([1,2,3,4]);

// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here

Здесь мы видим, что наша переменная j известна только в первом цикле, но не раньше и не позже. Но наша переменная i известна во всей функции.

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

Безопасно ли использовать переменные области блока сегодня?

Независимо от того, безопасно ли оно использовать сегодня, зависит от вашей среды:

  • Если вы пишете код на стороне сервера ( Node.js ), вы можете безопасно использовать оператор let .

  • Если вы пишете код JavaScript на стороне клиента и используете транспилер (например, Traceur ), вы можете безопасно использовать оператор let , однако ваш код, скорее всего, будет оптимальным в отношении производительности.

  • Если вы пишете код JavaScript на стороне клиента и не используете транспилер, вам необходимо рассмотреть поддержку браузера.

    Сегодня, 23 февраля 2016 года, это некоторые браузеры, которые либо не поддерживают, либо поддерживают лишь частичную поддержку:

    • Internet explorer 10 и ниже (без поддержки)
    • Firefox 43 и ниже (без поддержки)
    • Safari 9 и ниже (без поддержки)
    • Opera Mini 8 и ниже (без поддержки)
    • Android-браузер 4 и ниже (без поддержки)
    • Opera 36 и ниже (частичная поддержка)
    • Chome 51 и ниже (частичная поддержка)

Как отслеживать поддержку браузера

Для актуального обзора того, какие браузеры поддерживают оператор let во время вашего чтения этого ответа, см. Эту страницу « Can I Use .

(*) Глобальные и функционально скопированные переменные могут быть инициализированы и использованы до того, как они будут объявлены, поскольку переменные JavaScript будут hoisted . Это означает, что объявления всегда находятся в верхней части области.

(**) Заблокированные переменные диапазона не поднимаются


Я обнаружил, что многие люди, не знакомые с JavaScript, с трудом понимают, что наследование доступно по умолчанию на языке, а область возможностей - единственная область действия. Я предоставил расширение для beautifier, который я написал в конце прошлого года под названием JSPretty. Функция цветовой функции функции в коде и всегда связывает цвет для всех переменных, объявленных в этой области. Закрытие визуально демонстрируется, когда переменная с цветом из одной области видимости используется в другой области.

Попробуйте воспользоваться функцией:

См. Демонстрацию по адресу:

Просмотрите код по адресу:

В настоящее время функция предлагает поддержку глубины 16 вложенных функций, но в настоящее время не цветные глобальные переменные.


Современные Js, ES6 +, ' const ' и ' let '

Вы должны использовать область охвата для каждой переменной, которую вы создаете, как и большинство других основных языков. var устарел . Это делает ваш код более безопасным и более удобным.

const следует использовать в 95% случаев . Это делает так, чтобы переменная ссылка не могла измениться. Свойства массива, объекта и DOM могут меняться и, вероятно, быть const .

let должен использоваться для любой переменной, ожидающей переназначения. Это включает в себя цикл for. Если вы измените значение за пределами инициализации, используйте let .

Область блока означает, что переменная будет доступна только в скобках, в которых она объявлена. Это распространяется на внутренние области, включая анонимные функции, созданные в рамках вашей области.


В EcmaScript5 есть в основном две области, локальная область действия и глобальная область действия, но в EcmaScript6 мы имеем в основном три области, локальную область действия, глобальную область действия и новую область, называемую областью блока .

Пример области блока:

for ( let i = 0; i < 10; i++)
{
 statement1...
statement2...// inside this scope we can access the value of i, if we want to access the value of i outside for loop it will give undefined.
}

Чтобы добавить к другим ответам, область видимости - это список всех объявленных идентификаторов (переменных) и применяется строгий набор правил относительно того, как они доступны для текущего кода. Этот поиск может быть предназначен для назначения переменной, которая является ссылкой LHS (левая сторона), или может быть использована для извлечения ее значения, которое является ссылкой RHS (справа). Эти образы - это то, что движок JavaScript делает внутренне, когда он компилирует и выполняет код.

Итак, с этой точки зрения, я думаю, что картина поможет мне, которую я нашел в книге Scopes and Closures Kyle Simpson:

Цитата из его книги:

Здание представляет собой набор правил вложенных областей нашей программы. Первый этаж здания представляет собой выполняемую вами область действия, где бы вы ни находились. Верхний уровень здания - глобальный масштаб. Вы разрешаете ссылки LHS и RHS, просматривая ваш текущий этаж, и если вы его не найдете, выйдя на лифте на следующий этаж, глядя туда, затем на следующий и так далее. Как только вы попадете на верхний этаж (глобальный охват), вы либо найдете то, что ищете, либо нет. Но вы должны остановиться, несмотря ни на что.

Одно замечание, которое стоит упомянуть: «Сканирование в масштабе видится, когда оно найдет первое совпадение».

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


Вот пример:

<script>

var globalVariable = 7; //==window.globalVariable

function aGlobal( param ) { //==window.aGlobal(); 
                            //param is only accessible in this function
  var scopedToFunction = {
    //can't be accessed outside of this function

    nested : 3 //accessible by: scopedToFunction.nested
  };

  anotherGlobal = {
    //global because there's no `var`
  }; 

}

</script>

Вы захотите исследовать закрытие и как использовать их для создания частных членов .


Глобальный масштаб:

Глобальные переменные в точности похожи на глобальные звезды (Джеки Чан, Нельсон Мандела). Вы можете получить к ним доступ (получить или установить значение) из любой части вашего приложения. Глобальные функции похожи на глобальные события (Новый год, Рождество). Вы можете выполнять (вызывать) их из любой части вашего приложения.

//global variable
var a = 2;

//global function
function b(){
   console.log(a);  //access global variable
}

Локальная область:

Если вы находитесь в США, вы можете узнать Ким Кардашян, печально известную знаменитость (ей как-то удается сделать таблоиды). Но люди за пределами США не узнают ее. Она местная звезда, привязанная к своей территории.

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

function b(){
   var d = 21; //local variable
   console.log(d);

   function dog(){  console.log(a); }
     dog(); //execute local function
}

 console.log(d); //ReferenceError: dddddd is not defined    

Проверьте эту статью для углубленного понимания сферы применения


Я понимаю, что существует 3 области: глобальный охват, доступный во всем мире; локальная область действия, доступная для целой функции независимо от блоков; и область блока, доступная только для блока, оператора или выражения, на котором оно было использовано. Глобальная и локальная область обозначаются ключевым словом «var», либо внутри функции, либо снаружи, а область блока указывается ключевым словом «let».

Для тех, кто считает, что существует только глобальная и локальная область, объясните, почему Mozilla будет иметь всю страницу, описывающую нюансы области блока в JS.

let



Идея определения области видимости в JavaScript, когда она была первоначально разработана Бренданом Эйхом, взята из HyperCard скриптового языка HyperTalk .

На этом языке дисплеи были сделаны аналогично стопке индексных карточек. Была основная карта, называемая фоном. Он был прозрачным и может рассматриваться как нижняя карта. Любой контент на этой базовой карте делился с картами, расположенными поверх нее. Каждая карта, размещенная сверху, имела собственный контент, который имел приоритет над предыдущей картой, но при желании имел доступ к предыдущим картам.

Именно так разработана система обзора JavaScript. У него просто разные имена. Карты в JavaScript известны как Execution Contexts ECMA . Каждый из этих контекстов содержит три основные части. Переменная среда, лексическая среда и эта привязка. Возвращаясь к ссылке на карты, лексическая среда содержит весь контент из предыдущих карт ниже в стеке. Текущий контекст находится в верхней части стека, и любое содержимое, объявленное там, будет храниться в переменной среде. Переменная среда будет иметь приоритет в случае коллизий имен.

Эта привязка укажет на содержащий объект. Иногда контексты или контексты выполнения изменяются без изменения объекта-объекта, например, в объявленной функции, где содержащий объект может быть window или функцией-конструктором.

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

Так что это техническое объяснение. На практике важно помнить, что в JavaScript

  • Области являются технически «Контексты выполнения»
  • Контексты образуют стек окружений, в которых хранятся переменные
  • Верх верхнего уровня имеет приоритет (нижний - глобальный контекст)
  • Каждая функция создает контекст выполнения (но не всегда новую привязку)

Применяя это к одному из предыдущих примеров (5. «Закрытие») на этой странице, можно следить за стеком контекстов выполнения. В этом примере в стеке есть три контекста. Они определяются внешним контекстом, контекстом в вызываемой немедленно функции, называемой var six, и контекстом в возвращаемой функции внутри непосредственно вызываемой функции var six.

i ) Внешний контекст. Он имеет переменную среду a = 1
ii ) В контексте IIFE он имеет лексическую среду a = 1, но переменная среда a = 6, которая имеет приоритет в стеке
iii ) Возвращенный контекст функции, он имеет лексическую среду a = 6, и это значение, указанное в предупреждении при вызове.


JavaScript имеет только два типа области:

  1. Глобальный масштаб : глобальный - это не что иное, как область уровня окна. Здесь переменная присутствует во всем приложении.
  2. Функциональная область : переменная, объявленная внутри функции с ключевым словом var имеет функциональную область.

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

        a = "global";
         function outer(){ 
              b = "local";
              console.log(a+b); //"globallocal"
         }
outer();

Цепочка области ->

  1. Уровень окна - a и outer функция находятся на верхнем уровне в цепочке видимости.
  2. когда внешняя функция, называемая variable scope object новой variable scope object (и включаемой в цепочку областей), добавляется с переменной b внутри нее.

Теперь, когда требуется переменная a она сначала ищет ближайшую область переменной, и если переменная не существует, то она перемещается в следующий объект цепочки переменных переменной. В этом случае это уровень окна.


Каждый фрагмент кода JavaScript (глобальный код или функции) имеет связанную с ним цепочку областей видимости. Эта цепочка областей видимости - это список или цепочка объектов, которые определяют переменные, которые являются «в области» для этого кода. Когда JavaScript нужно искать значение переменной x (процесс, называемый переменным разрешением ), он начинается с поиска первого объекта в цепочке. Если этот объект имеет свойство с именем x , используется значение этого свойства. Если первый объект не имеет свойства с именем x , JavaScript продолжает поиск со следующим объектом в цепочке. Если второй объект не имеет свойства с именем x , поиск переходит к следующему объекту и так далее. Если x не является свойством какого-либо из объектов в цепочке областей видимости, то x не является видимым для этого кода, и возникает ошибка ReferenceError. В коде JavaScript верхнего уровня (т. Е. Код, не содержащийся в каких-либо определениях функций) цепочка областей видимости состоит из одного объекта, глобального объекта. В не-вложенной функции цепочка областей видимости состоит из двух объектов. Первый - это объект, который определяет параметры функции и локальные переменные, а второй - глобальный объект. Во вложенной функции цепочка областей действия имеет три или более объектов. Важно понять, как создается эта цепочка объектов. Когда функция ОПРЕДЕЛЕНА , она сохраняет цепочку областей действия в действии. Когда эта функция INVOKED , она создает новый объект для хранения своих локальных переменных и добавляет этот новый объект в цепочку хранимых цепей для создания новой более длинной цепочки, которая представляет область действия для этой функции. Это становится более интересным для вложенных функций, потому что каждый раз, когда вызывается внешняя функция, внутренняя функция определяется снова.Поскольку цепочка областей действия различна для каждого вызова внешней функции, внутренняя функция будет тонко различной при каждом ее определении - код внутренней функции будет идентичным при каждом вызове внешней функции, но цепочка областей, связанная с этим код будет другим . Это понятие цепи видимости имеет решающее значение для понимания закрытий.


Попробуйте этот любопытный пример. В приведенном ниже примере, если a было числовым, инициализированным в 0, вы увидите 0, а затем 1. За исключением того, что a - объект, а javascript передает f1 указатель на не его копию. В результате вы получаете одинаковое предупреждение одновременно.

var a = new Date();
function f1(b)
{
    b.setDate(b.getDate()+1);
    alert(b.getDate());
}
f1(a);
alert(a.getDate());

Javascript использует цепочки областей видимости для определения области действия данной функции. Обычно существует одна глобальная область видимости, и каждая определенная функция имеет собственную вложенную область. Любая функция, определенная внутри другой функции, имеет локальную область, связанную с внешней функцией. Это всегда место в источнике, которое определяет область действия.

Элемент в цепочке областей видимости - это в основном Map с указателем на его родительскую область.

При разрешении переменной javascript запускается в самой внутренней области и ищет внешний вид.


В JavaScript есть два типа области:

  • Локальная область
  • Глобальный охват

Функция «Ниже» имеет локальную переменную области carName. И эта переменная недоступна извне функции.

function myFunction() {
    var carName = "Volvo";
    alert(carName);
    // code here can use carName
}

В классе ниже приведена глобальная переменная carName. И эта переменная доступна извне в классе.

class {

    var carName = " Volvo";

    // code here can use carName

    function myFunction() {
        alert(carName);
        // code here can use carName 
    }
}

запустите код. надеюсь, что это даст представление о

Name = 'global data';
document.Name = 'current document data';
(function(window,document){
var Name = 'local data';
var myObj = {
    Name: 'object data',
    f: function(){
        alert(this.Name);
    }
};

myObj.newFun = function(){
    alert(this.Name);
}

function testFun(){
    alert("Window Scope : " + window.Name + 
          "\nLocal Scope : " + Name + 
          "\nObject Scope : " + this.Name + 
          "\nCurrent document Scope : " + document.Name
         );
}


testFun.call(myObj);
})(window,document);

Global: переменная, объявленная вне функции

Локальный: переменная, объявленная внутри функции, и может быть вызвана только в этой области


В ALMOST есть только два типа областей JavaScript:

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

Таким образом, любые блоки, отличные от функций, не создают новую область. Это объясняет, почему for-loops перезаписывают внешние облачные переменные:

var i = 10, v = 10;
for (var i = 0; i < 5; i++) { var v = 5; }
console.log(i, v);
// output 5 5

Вместо этого используйте функции:

var i = 10, v = 10;
$.each([0, 1, 2, 3, 4], function(i) { var v = 5; });
console.log(i,v);
// output 10 10

В первом примере не было области блока, поэтому первоначально объявленные переменные были перезаписаны. Во втором примере из-за функции появилась новая область, поэтому первоначально объявленные переменные были SHADOWED, а не перезаписаны.

Это почти все, что вам нужно знать с точки зрения охвата JavaScript, за исключением:

  • try / catch вводит новую область ТОЛЬКО для самой переменной исключения, другие переменные не имеют новой области
  • with-clause - это, по-видимому, другое исключение, но с использованием предложения с его предложением очень не рекомендуется ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with )

Таким образом, вы можете видеть, что область обзора JavaScript на самом деле чрезвычайно проста, хотя и не всегда интуитивная. Несколько вещей, о которых нужно знать:

  • объявления var отображаются вверху области. Это означает, что независимо от того, где происходит объявление var, компилятору это похоже на то, что сам var происходит наверху
  • множественные объявления var в пределах одной области объединены

Итак, этот код:

var i = 1;
function abc() {
  i = 2;
  var i = 3;
}
console.log(i);     // outputs 1

эквивалентно:

var i = 1;
function abc() {
  var i;     // var declaration moved to the top of the scope
  i = 2;
  i = 3;     // the assignment stays where it is
}
console.log(i);

Это может показаться противоречивым, но это имеет смысл с точки зрения императивного разработчика языка.


1) Существует глобальная область видимости, область действия и области поиска и захвата. В общем случае для переменных не существует области уровня «block». Операторы «with» и «catch» добавляют имена к своим блокам.

2) Области привязаны к функциям вплоть до глобальной области.

3) Свойства разрешаются путем прохождения цепи прототипа. Оператор WITH присваивает имена объектов объектам в лексической области, определенной блоком с.

EDIT: ECMAAScript 6 (Harmony) предлагается поддерживать let, и я знаю, что chrome позволяет флаг «гармонии», поэтому, возможно, он его поддерживает.

Пусть будет поддержка для определения уровня блока, но вы должны использовать ключевое слово, чтобы оно произошло.

EDIT: Основываясь на том, что Бенджамин указывает на высказывания и комментарии в комментариях, я отредактировал сообщение и добавил больше. Оба оператора with и catch задают переменные в своих соответствующих блоках, и это область блоков. Эти переменные смещены к свойствам объектов, переданных в них.

 //chrome (v8)

 var a = { 'test1':'test1val' }
 test1   // error not defined
 with (a) { var test1 = 'replaced' }
 test1   // undefined
 a       // a.test1 = 'replaced'

EDIT: Пример разъяснения:

test1 привязан к блоку с, но сглажен к a.test1. «Var test1» создает новую переменную test1 в верхнем лексическом контексте (функции или глобальном), если только он не является свойством a, которое оно есть.

Хлоп! Будьте осторожны, используя 'with' - так же, как var является noop, если переменная уже определена в функции, она также является noop в отношении имен, импортированных из объекта! Немного хедз-ап на имя, которое уже определено, сделало бы это намного безопаснее. Из-за этого лично я никогда не буду использовать.


В JS есть только области функций. Не блокируйте области! Вы также видите, что такое подъем.

var global_variable = "global_variable";
var hoisting_variable = "global_hoist";

// Global variables printed
console.log("global_scope: - global_variable: " + global_variable);
console.log("global_scope: - hoisting_variable: " + hoisting_variable);

if (true) {
    // The variable block will be global, on true condition.
    var block = "block";
}
console.log("global_scope: - block: " + block);

function local_function() {
    var local_variable = "local_variable";
    console.log("local_scope: - local_variable: " + local_variable);
    console.log("local_scope: - global_variable: " + global_variable);
    console.log("local_scope: - block: " + block);
    // The hoisting_variable is undefined at the moment.
    console.log("local_scope: - hoisting_variable: " + hoisting_variable);

    var hoisting_variable = "local_hoist";
    // The hoisting_variable is now set as a local one.
    console.log("local_scope: - hoisting_variable: " + hoisting_variable);
}

local_function();

// No variable in a separate function is visible into the global scope.
console.log("global_scope: - local_variable: " + local_variable);

ES6: Как уже упоминалось в большинстве ответов, в ES6 вы можете просто инициализировать параметр вместе со значением.

ES5: Большинство из приведенных ответов недостаточно для меня, потому что есть случаи, когда мне, возможно, придется передавать ложные значения, такие как 0 , null и undefined для функции. Чтобы определить, является ли параметр неопределенным, потому что это значение, которое я передал вместо неопределенного из-за того, что не было определено вообще, я делаю это:

function foo (param1, param2) {
   param1 = arguments.length >= 1 ? param1 : "default1";
   param2 = arguments.length >= 2 ? param2 : "default2";
}




javascript function variables scope var