2015-05-02 4 views
3

Немного смущенный этим Красноречивым Javascript explanation параметров и областей применения.javascript параметры и области применения

В нем указано, что переменные, объявленные вне функции, являются глобальными, переменные, объявленные внутри функции, являются локальными, а переменные, объявленные внутри функции без предшествующего var, по существу ссылаются на глобальную переменную с аналогичным именем. Хорошо. В этом есть смысл. Но тогда этот код бросает меня за цикл.

var x = "outside"; 

var f1 = function() { 
    var x = "inside f1"; 
}; 
f1(); 
console.log(x); 
// → outside 

var f2 = function() { 
    x = "inside f2"; 
}; 
f2(); 
console.log(x); 
// → inside f2 

логофф значение х в первой функции должен результат «внутри f1», так как эта переменная была объявлена ​​локально. И эта вторая функция (заключающаяся в том, что она содержит переменную, объявленную без var и, таким образом, ссылается на глобальную, объявленную вверху) должен привести к «наружу». Но ... в любом случае это не так.

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

ответ

1

Переменные, объявленные внутри функции доступны только (или scoped) внутри этих функций. Образец может более ясно, если бы это было так:

function f1() { 
    var x = "Inside f1"; 
} 

console.log(x); 

приведет к

ReferenceError: x is not defined 

Однако функции, которые имеют переменную, объявленную без var является implicit global (и как плохая практика, или пропущенная ошибка):

function f2() { 
    y = "Inside f2"; 
} 

console.log(y); 

Будет работать так, как вы ожидаете, а также объявлять неявный глобальный.

Следует упомянуть "use strict";, в котором содержится код в E S5's Strict Mode. Обычно вы хотите объявить это внутри функции, которая заставляет функцию запускаться в строгом режиме и avoids the semantics of strict mode from breaking interoptability с другим кодом.

function f3() { 
    "use strict"; 
    z = "Inside f3"; 
} 

console.log(z); 

приведет к

ReferenceError: z is not defined 

Поскольку строгий режим не позволяет объявить неявное глобальным.


Чтобы уточнить, исходя из ваших комментариев, неявные глобальные переменные будут «перезаписывать» друг друга. Более ясно, используя терминологию JavaScript:

  • x = 10 будет объявить свойство на глобальный объект окружающей среды в x, либо window.x для среды браузера и global.x для окружающей среды/IO узла.
  • x = 20 переопределит те же свойства, о которых говорилось выше.

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

function functionThatNeedsGreaterThan50(value) { 
    // Skip checking the parameter because we trust the 
    // other developers on the team to make sure they call 
    // this right. 
} 

function f4() { 
    q = 42; 
} 

function f5() { 
    q = 62; 
} 

f4(); 
f5(); 

console.log(q); 

// sometime thousands of calls later, one of which was 
f4(); 

// I thought this was 62 but 

functionThatNeedsGreaterThan50(q); 
+0

Я знаю, что принял это как ответ вчера вечером, но ... что случилось с объявлением неявного глобального? Я полагаю, что это делает труднее найти источник любых потенциальных ошибок, возникающих в результате этого. Поскольку глобальная переменная не определена сверху, как другие * обычные * глобальные переменные. Правильно? – sabaeus

+0

Нм, просто прочитайте свою ссылку на неявные глобальные значения. – sabaeus

+1

@sabaeus Я добавил и собственные мысли. – jdphenix

3

x в f1 новая переменная доступны только в f1 и не оказывает никакого влияния на первый, глобальный x. Пример кода в вашем вопросе может по существу быть записано как следующий для ясности:

var globalX = "outside"; 
    var f1 = function() { 
     var localF1X = "inside f1"; 
    }; 
    f1(); 
    console.log(globalX); // → outside 

    var f2 = function() { 
     globalX = "inside f2"; 
    }; 
    f2(); 
    console.log(globalX); // → inside f2 
1

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

Вы можете прочитать больше о переменных JavaScript и "грузоподъемных" здесь: http://javascriptissexy.com/javascript-variable-scope-and-hoisting-explained/

Поэтому:

var x = 'a'; 
function f1() { 
    var x = 1; 
    console.log(x); 
} 

f1(); //outputs 1 
console.log(x); //outputs 'a' 

function f2() { 
    x = 'b'; 
} 

console.log(x); //still outputs 'a' 

f2(); 

console.log(x); //now outputs 'b' 
Смежные вопросы