Являются ли переменные статически или динамически «ограничены» в JavaScript? - PullRequest
30 голосов
/ 06 июня 2009

Или более конкретно, что мне нужно:

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

myVar=0;

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

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

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

Ответы [ 7 ]

47 голосов
/ 06 июня 2009

Джефф прав. Обратите внимание, что на самом деле это не очень хороший тест на статическое определение объема (что имеет 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 в предупреждении, поскольку предупреждение не наследует область действия из любой функции.

4 голосов
/ 06 июня 2009

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

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

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

3 голосов
/ 06 июня 2009

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

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

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

1 голос
/ 20 июня 2011

Если вы не используете ключевое слово var для определения своих переменных, все в конечном итоге становится свойством объекта window. Таким образом, ваш код будет эквивалентен следующему:

window.myVar=0;

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

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

Если вы помните об этом, всегда должно быть ясно, что происходит.

0 голосов
/ 02 июля 2017
myVar=0;

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

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

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

0 голосов
/ 08 января 2015

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

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.

0 голосов
/ 06 июня 2009

Насколько я понимаю, любая переменная без ключевого слова var обрабатывается global , с ней ее локальная область видимости, поэтому:

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

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

В качестве хорошей практики JS рекомендуется ВСЕГДА добавлять ключевое слово var .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...