2009-06-06 2 views
23

или более конкретно к чему мне нужно:Являются ли переменные статически или динамически «облачными» в javascript?

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

myVar=0; 

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

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

Что MYVAR в конечном итоге, если CallME() вызывается через Runme()?

+11

Почему бы вам не запустить его и не выяснить? –

+0

Не лучше ли документировать вопрос, чтобы другие могли его видеть? – affinehat

ответ

39

Jeff is right. Обратите внимание, что на самом деле это не хороший тест статического охвата (который имеет JS). Лучше один будет:

myVar=0; 

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

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

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

В статический контекстном языке (как JS), что предупреждает 10 и 0. вар MYVAR (локальные переменный) в Runme тень глобального MYVAR в этой функции. Тем не менее, это не имеет никакого эффекта в CallME, так CallME использует глобальный MYVAR, который все еще находится на 0.

В динамически контекстном языке (в отличии от JS), CallME унаследует объем от Runme, так AddMe станет 20. Обратите внимание, что myVar все равно будет 0 при оповещении, потому что предупреждение не наследует область действия от любой функции.

+9

Исключением является ключевое слово 'this', которое ведет себя как переменная с динамической областью – Jaksa

3

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

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

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

+0

i означало просмотр области ... – kylex

2

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

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

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

0

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

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

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

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

1

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

window.myVar=0; 

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

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

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

0

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

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
myVar=0; 

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

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

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

Смежные вопросы