Являются ли переменные статически или динамически "скопированы" в javascript?
Или более конкретным для того, что мне нужно:
Если я вызову функцию из другой функции, она собирается вытащить переменную из вызывающей функции или с уровня выше? Пример:
myVar=0;
function runMe(){
myVar = 10;
callMe();
}
function callMe(){
addMe = myVar+10;
}
Что делает myVar в том случае, если callMe() вызывается через runMe()?
Ответы
Ответ 1
Джефф прав. Обратите внимание, что на самом деле это не хороший тест статического охвата (который имеет 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 в оповещении, потому что предупреждение не наследует область видимости от любой функции.
Ответ 2
если ваша следующая строка callMe();, то addMe будет равно 10, а myVar будет 0.
если ваша следующая строка runMe();, то addMe будет равно 20, а myVar будет равно 10.
Простите меня за вопрос - что это связано со статическим/динамическим связыванием? Разве myVar не является глобальной переменной и не будет обрабатывать процедурный код (разворачивать все в стек вызовов)?
Ответ 3
Переменные статически привязаны к JavaScript (динамическое масштабирование - действительно довольно грязный бизнес: вы можете больше узнать об этом на Wikipedia).
В вашем случае, однако, вы используете глобальную переменную, поэтому все функции будут иметь доступ к этой же переменной. Ответ Matthew Flaschen показывает, как вы можете изменить его, так что второй myVar на самом деле является другой переменной.
Эта страница объясняет, как объявлять глобальные и локальные переменные в JavaScript, если вы не слишком хорошо знакомы с ней. Это отличается от того, как это делают большинство языков сценариев. (Вкратце: ключевое слово "var" делает переменную local, если она объявлена внутри функции, иначе переменная глобальна.)
Ответ 4
Если вы не используете ключевое слово var
для определения своих переменных, все становится свойством объекта window
. Таким образом, ваш код будет эквивалентен следующему:
window.myVar=0;
function runMe(){
window.myVar = 10;
window.callMe();
}
function callMe(){
window.addMe = window.myVar+10;
}
Если вы помните об этом, всегда должно быть ясно, что происходит.
Ответ 5
Насколько я понимаю, любая переменная без ключевого слова var рассматривается глобально, с ее локальным областью, поэтому:
// This is a local scoped variable.
var local_var = "something";
// This is a global scoped variable.
global_var = "something_else";
Как хорошая практика JS, рекомендуется ВСЕГДА добавить ключевое слово var.
Ответ 6
Я хотел бы добавить, что лямбда-выражения также статически охвачены местоположением, в котором определено выражение. Например,
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.
Ответ 7
myVar=0;
function runMe(){
myVar = 10;
callMe();
}
function callMe(){
addMe = myVar+10;
}
Что касается вывода, то myVar и addMe будут в этом случае глобальными переменными, как в javascript, если вы не объявляете переменную с var, то она неявно объявляет ее глобально, когда вы вызываете runMe(), тогда myVar будет иметь значение 10, а addMe - 20.