2013-03-14 3 views
0

Я хотел бы, чтобы понять разницу между:Передача переменных VS проходных значений

var the_timeout = setTimeout("alert(the_string);", 60000); 

и:

var the_timeout = setTimeout("alert(" + the_string + ");",60000); 

Я понимаю, что первая проходит переменную, а второй передает значение - но что это значит и почему это имеет значение? Почему значение передается во втором примере?

Кроме того (я надеюсь, что это тот же предмет), почему это работает:

var timeout=setTimeout("someFunction();", 3000) 

Хотя это не делает:

var timeout=setTimeout(someFunction(),3000); 

При вызове функции, someFunction() работы, так почему мне нужно добавить котировки при использовании setTimeout()?

+0

«Я понимаю, что первая передает переменную, а вторая передает значение» --- мм, что? – zerkms

+1

Простое решение: просто забудьте, что 'setTimeout' может принимать строки - это ужасная практика. ** Всегда ** передавать обратные вызовы. – zerkms

+1

@frrlod Вы вводите себя в заблуждение поведением 'setTimeout()' и понятий pass-by-values ​​и pass-by-reference. Я предлагаю перефразировать вопрос. – sweetamylase

ответ

1

Это синтаксический анализ выполнения кода в пределах строки, 60 секунд спустя.

var the_string = "Hello"; 
setTimeout("alert(the_string);", 60000); 
the_string = "Goodbye"; 

Это означает, что alert(the_string) выполняется так же, как если бы это был регулярный код. Поэтому он предупредил «До свидания». Это связано с тем, что, когда код в конечном итоге выполняется, обновленное значение the_string используется, поскольку вы передаете переменную.

Но это делает что-то тонко другое.

var the_string = "Hello"; 
setTimeout("alert(" + the_string + ");",60000); 
the_string = "Goodbye"; 

Теперь мы создаем новый фрагмент кода на лету. Создаваемый фрагмент alert(Hello);. Но Hello - переменная без значения, потому что вы не получили правильные цитаты.

Но позволяет сказать, что вы имели в виду это:

var the_string = "Hello"; 
setTimeout("alert('" + the_string + "');",60000); 
the_string = "Goodbye"; 

Теперь это будет работать, так как код он генерирует это alert('Hello');. Кажется, что на первый взгляд делает то же самое. Но поскольку сгенерированный код теперь содержит буквально жестко закодированную строку, поэтому при изменении the_string изменение не превращает его в сгенерированный код, потому что он был жестко закодирован в фрагмент.

Исходя из этого, это просто:

setTimeout("someFunction();", 3000) 

код в строке выполняется после задержки. В этом случае выполняется someFunction().

Но это совершенно разные:

setTimeout(someFunction(),3000); 

В этом случае someFunction() является выполняется немедленно, и это возвращаемого значения передаются в качестве первого аргумента функции setTimeout(). Поэтому он не будет делать то, что вы ожидаете.


Большинство это связано с причудами eval и сгенерированного кода, как setTimeout(string,delay) является формой eval. И ничто из этого не является проблемой, если вы не используете eval, и вы не передаете строку setTimeout().

Передача строки в setTimeout приводит к eval, eval приводит к Wierd сумасшедший ошибки, странные безумные ошибки приводят к боли, боль приводит к sufferrriing.

Вместо этого вы передаете функцию вместо этого. Это лучше всего.

// pass an anonymous function to run some code later 
var the_string = "Hello"; 
setTimeout(function() { 
    alert(the_string); 
}, 60000); 
the_string = "Goodbye"; 
// alerts "Goodbye" 60 seconds later 


// pass an anonymous function to run some code 
setTimeout(function() { 
    someFunction(); 
}, 3000); 

// or pass a reference to a function to execute, note lack of() 
setTimeout(someFunction, 3000); 
5

Я думаю, вы смешиваете различие между передачей по значению и передачей по ссылке с этим. В приведенных примерах нет разницы.

Однако

var timeout=setTimeout("someFunction();", 3000) 

Работы и:

var timeout=setTimeout(someFunction(),3000); 

Не потому, что во втором случае, someFunction() будет работать так, что он может затем передать результат/возвращаемое значение setTimeout. Вот почему вы передаете его как строку, так что setTimeout может eval это само по себе. Если, конечно, если someFunction() сам возвращает функцию, которую setTimeout может использовать в качестве обратного вызова.

Однако, как zerkms отметил в комментарии, вы должны пройти обратные вызовы вместо:

var timeout = setTimeout(function() { someFunction(); }, 3000); 

Это также эффект, который setTimeout может затем вызвать функцию обратного вызова всякий раз, когда он хочет. Главным преимуществом является то, что вы можете передать любую регулярную функцию, так что вы можете воспользоваться редактором вы можете использовать вместо упаковки все это в строку:

var myTrigger = function() { 
    someFunction(); 
}; 

var timeout = setTimeout(myTrigger, 3000); 
Смежные вопросы