2013-06-16 3 views
1

Извините, если моя терминология отключена в этом вопросе.Основы - Переменная Ссылка

Возьмем следующую функцию:

i = 1; 
v = i * 2; 

for (j = 0; j < 4; j++) { 
    console.log(v); 
    i++; 
    } 

Консоль вернется 2, 2, 2, 2. Когда я столкнулся с этим я переместил переменной «V» внутри для цикла и возвращает ожидаемые значения 2, 4, 6, 8. Мое понимание того, как переменные работают на фундаментальном уровне, очевидно, ошибочно.

Моя логика подсказывает, что значение переменной v постоянно связано со значением переменной i. Таким образом, каждый раз, когда ссылается на v, нужно также указать значение i. Так как i будет численно увеличиваться, то v должно увеличиваться пропорционально этому. Вместо этого оказывается, что значение result из v сохраняется, а не фактическое выражение, которое первоначально вычисляет это значение.

Это первый вопрос о принципах, и пока мне удалось найти решение проблемы, я не понимаю, почему это решение сработало.

+0

Абсолютная промаха, разрешенная сейчас. –

ответ

2

первый способ

i = 1; 
// v is equal to the result of "i * 2" (2) and will stay that way 
// until it (v) is set to another value (which never happens) 
v = i * 2; 

for (j = 0; j < 4; j++) { 
    console.log(v); 
    i++; 
} 

второй путь

i = 1; 

for (j = 0; j < 4; j++) { 
    // v is equal to i*2, we are setting v each iteration. in each iteration, i is 
    // changed. so the value of v will be different 
    v = i * 2; 
    console.log(v); 
    i++; 
} 

Если по каким-либо причинам вы не хотите явно установить v каждый раз внутри цикла, вы можете создать функцию:

i = 1; 
v = function(){ return i * 2 }; 

for (j = 0; j < 4; j++) { 
    console.log(v()); 
    i++; 
} 
+0

Интересная идея с функцией. Возможно, это можно использовать с геттерами для создания переменных, которые выглядят как переменные, но вместо этого являются функциями. –

2

Да, переменные будут хранить только фактическое значение, которое было присвоено им, и а не логика, которая создала это значение.

Так эта строка кода:

v = 2 * i; 

рассчитает 2 * i, а затем создает переменную v, что указывает на результат расчета. Итак, это должно объяснить, почему ваш первый пример не работает так, как он был предназначен.

В вас втором примере вы положили, что Постулаты внутри для цикла:

for (...) { 
    v = 2 * i; 
    i++; 
} 

Теперь v будет переназначен на каждой итерации и выражение 2 * i будет reevaluted каждый раз. И так как i увеличивается на каждой итерации, то также увеличивается v, что приводит к желаемому результату.

+0

Что касается сохраняемого значения, а не выражения, используемого для их создания, есть ли причина для этого? –

+1

, это приведет к увеличению времени выполнения и использования памяти, особенно если вы рассматриваете длинные цепочки, например 'var a = 1; var b = a + 1; var c = b + 1; ... '. Также вы можете создавать круговые зависимости: 'var a = 1; var b = a + 1; a = b + 1; 'Что такое и что такое' b' в этом примере? – basilikum

+0

Это хороший ответ, спасибо. –

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