Есть ли цель переопределить переменные JavaScript? - PullRequest
6 голосов
/ 08 декабря 2009

Я новичок в JavaScript.

<html>
<body>
<script type="text/javascript">
var x=5;
document.write(x);
document.write("<br />");
var x;
document.write(x);
</script>
</body>
</html>

Результат:

5
5

Когда x объявляется во второй раз, оно должно быть неопределенным, но оно сохраняет предыдущее значение. Пожалуйста, объясните, имеет ли это объявление какое-либо специальное назначение.

Ответы [ 9 ]

20 голосов
/ 08 декабря 2009

Вы на самом деле не объявляете переменную заново.

Оператор переменной в JavaScript подлежит подъему, что означает, что они оцениваются в время разбора и позже в время выполнения назначения сделаны.

Ваш код в конце фазы анализа перед выполнением выглядит примерно так:

var x;
x = 5;

document.write(x);
document.write("<br />");
document.write(x);
7 голосов
/ 08 декабря 2009

var один не выполняет назначение. Он только указывает, что когда вы используете имя переменной во всей области действия, в которой встречается var, вы говорите о локальной переменной, а не о глобальной (спорная по умолчанию). var обнаруживается, когда функция анализируется и удерживается во всей этой области, поэтому то, куда вы ее поместили, не имеет значения:

var a= 0;

function foo() {
    a= 1;
    return a;
    var a;
}

var b= foo();
alert('global a='+a+', local a='+b);

Результат global a= 0, local a= 1: хотя оператор var никогда не достигается в ходе выполнения foo(), он по-прежнему эффективен для создания a локальной переменной.

Таким образом, объявление var x второй раз в той же области полностью избыточно. Однако иногда вы все равно можете это сделать, как правило, когда вы повторно используете имя локальной переменной для второго независимого использования в той же функции. Чаще всего:

for (var i= 0; i<onething.length; i++) {
    ...do some trivial loop...
}

for (var i= 0; i<anotherthing.length; i++) {
    ...do another trivial loop...
}

Хотя вы, конечно, можете опустить второй var, и такие инструменты, как jslint, потребуют от вас этого, на самом деле это не очень хорошая идея.

Представьте, что вы позже изменили или удалили первый цикл, чтобы он больше не объявлял i равным var. Теперь оставшийся второй цикл внезапно меняет значение с локальной на глобальную переменную. Если вы не замечаете при обновлении первого цикла, что второй цикл имеет скрытую зависимость от него (и вы вполне можете не заметить, что, учитывая то, как глаза скрывают шаблон for(...=0 ; ...<...; ...++) в «о, это просто стандартный итератор») ), у вас есть тонкая и раздражающая проблема отладки.

1 голос
/ 08 декабря 2009

поэтому, когда второй раз, когда объявленный x должен быть неопределенным

Какая часть спецификации говорит об этом?

«Неопределенное поведение» не означает «переменная будет undefined».

0 голосов
/ 21 декабря 2016

Я недавно написал код вроде:

var obj1 = get_an_object();
var v = obj1.get_velocity();
v += changes_in_velocity();
obj1.set_velocity(v);

var obj2 = get_an_object();
var v = obj2.get_velocity();
v += changes_in_velocity();
obj2.set_velocity(v);

(Фактический код был более сложным и менее повторяющимся)

Что касается браузера, второй оператор var v был излишним и бессмысленным. Для меня это служило двум целям. Он сказал забыть все, что я знал о старом v, потому что это было новое использование. И это означало, что я мог бы переупорядочить код или закомментировать первую половину, не нарушая ничего.

0 голосов
/ 08 декабря 2009

Вы должны никогда повторно объявить переменную в той же области видимости, если вы действительно хотите изменить это, назначьте его. Переопределение не требуется для создания другого объекта на этом динамическом языке, если вы хотите, чтобы x был строкой, просто присвойте:

x = "hello";

Не обязательно, чтобы вы установили его обратно в неопределенное значение или переопределили сначала.

Обратите внимание, что изменение типа переменной в большинстве случаев не очень хорошая практика, просто заявляя, что это возможно, если это то, что вам требуется.

0 голосов
/ 08 декабря 2009

Кроме того, программист может использовать var для локализации переменной:

<script>
var x= 'this is global x';
function my_x() {
 var x= 'localized x';
 alert(x);
}
my_x();
alert(x);
</script>
0 голосов
/ 08 декабря 2009

В пределах той же области действия совершенно не нужно «повторно декларировать» переменную.

0 голосов
/ 08 декабря 2009

Эта вторая переменная x совершенно лишняя.

0 голосов
/ 08 декабря 2009

Насколько я понимаю JavaScript, использование ключевого слова var совершенно необязательно в глобальной области действия . Это другая история для функций.

Внутри функции используйте ключевое слово var, чтобы указать, что переменная является локальной для функции (в отличие от глобальной по умолчанию).

Я лично использую var в глобальной области видимости, чтобы показать, что переменная объявляется и / или используется впервые.

Вы можете ссылаться на http://www.w3schools.com/js/js_variables.asp для получения дополнительной информации.

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