Переменные статически или динамически области видимости в JavaScript?

или что мне нужно:

Если я вызываю функцию из другой функции, собирается ли она вытащить переменную из вызывающей функции или с уровня выше? Ex:

myVar=0;

function runMe(){
    myVar = 10;
    callMe();
}

function callMe(){
   addMe = myVar+10;
}

что myVar в конечном итоге, если callMe () вызывается через runMe ()?

7 ответов


Джефф прав. Обратите внимание, что это на самом деле не хороший тест статической области обзора (который имеет JS). Лучше было бы:

myVar=0;

function runMe(){
    var myVar = 10;
    callMe();
}

function callMe(){
   addMe = myVar+10;
}

runMe();
alert(addMe);
alert(myVar);

на статически ограниченном языке (например, JS), который предупреждает 10 и 0. Var myVar (локальная переменная) в runMe затеняет глобальный myVar в этой функции. Однако это не влияет на callMe, поэтому callMe использует глобальный myVar, который по-прежнему равен 0.

на динамически ограниченном языке (в отличие от JS), callMe будет наследовать область от runMe, поэтому addMe станет 20. Обратите внимание, что myVar по-прежнему будет 0 в предупреждении, поскольку предупреждение не наследует область действия ни от одной из функций.


Если следующая строка callMe ();, тогда addMe будет 10, а myVar будет 0.

Если следующая строка runMe();, тогда addMe будет 20, а myVar будет 10.

Простите меня за вопрос - какое это имеет отношение к статической / динамической привязке? Не является ли myVar просто глобальной переменной, и не будет ли процедурный код (разворачивать все в стек вызовов) определять значения?


переменные статически ограничены в JavaScript (динамическая область видимости действительно довольно грязный бизнес: вы можете прочитать больше об этом на Википедия).

в вашем случае вы используете глобальную переменную, поэтому все функции будут обращаться к той же переменной. Ответ Мэтью горнолыжный подъемник flaschen показывает, как вы можете изменить его так, что второй аргумент myVar-это другая переменная.

На Этой Странице объясняет, как объявить глобальные и локальные переменные в JavaScript, если вы не слишком знакомы с ним. Это отличается от того, как это делают большинство скриптовых языков. (Вкратце: ключевое слово " var " делает переменную локальной, если она объявлена внутри функции, в противном случае переменная является глобальной.)


Если вы не используете ключевое слово var чтобы определить ваши переменные, все заканчивается тем, что свойство на


насколько я понимаю, любая переменная без var ключевое слово рассматривается глобальные, С ним, его локальная область, так:

// This is a local scoped variable.
var local_var = "something"; 

// This is a global scoped variable.
global_var = "something_else";

в качестве хорошей практики JS рекомендуется всегда добавлять var ключевое слово.


Я хотел бы добавить, что лямбда-выражения также статически ограничены в том месте, где определено выражение. Например,

var myVar = 0;

function foo() {
    var myVar = 10;
    return { bar: function() { addMe = myVar + 10; }}
}

var myObj = foo();

var addMe = 6;
alert(addMe);

myVar = 42;
myObj.bar();

alert(addMe);

появится 6 и 20.


myVar=0;

function runMe(){
    myVar = 10;
    callMe();
}

function callMe(){
   addMe = myVar+10;
}

что касается вывода, myVar и addMe оба будут глобальной переменной в этом случае, как в javascript, если вы не объявляете переменную с var, то она неявно объявляет ее как глобальную, следовательно, когда вы вызываете runMe (), то myVar будет иметь значение 10, а addMe будет иметь 20 .