Ссылка на значение JavaScript до его объявления - кто-то может объяснить это
Я надеюсь, что кто-то может объяснить мне, почему приведенный ниже JavaScript/HTML будет показывать "дверь № 2" при просмотре HTML в браузере:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script type="text/javascript">
function testprint() {
alert('door #1');
};
window.onload = testprint;
function testprint() {
alert('door #2');
};
testprint = function() {
alert('door #3');
};
</script>
<script type="text/javascript">
function testprint() {
alert('door #4');
};
</script>
</head>
<body>
</body>
</html>
Так как только декларация testprint
происходит раньше window.onload
установлен в testprint
Я бы ожидал window.onload
вызвать "дверь № 1", чтобы показать. На самом деле, нагрузка вызывает "дверь № 2". Обратите внимание, что это будет сделано, будь то первое объявление testprint
включен или нет.
Третья и четвертая декларация testprint
использовать разные способы назначения функции, я попробовал это, чтобы увидеть, если она переопределит window.onload
То же самое было второй декларацией testprint
делает. Это не так. Обратите внимание, что если я переместить четвертое объявление testprint
до конца первого блока скрипта он будет вызван window.onload
,
3 ответа
Объявления функций являются предметом подъема, и они оцениваются во время разбора, путем подъема означает, что они доступны для всей области, в которой они были объявлены, например:
foo(); // alerts foo
foo = function () { alert('bar')};
function foo () { alert('foo');}
foo(); // alerts bar
Первый звонок foo
выполнит объявление функции, потому что во время разбора она стала доступной, второй вызов foo
выполнит выражение функции, объявленное во время выполнения.
Для более подробного обсуждения различий между выражениями функций и объявлениями функций, проверьте этот вопрос и эту статью.
Причина #3 не меняет window.onload в том, что функции вызываются по ссылке, а не по имени. Когда вы установите window.onload = testprint
, он присваивает ссылку на текущее значение testprint
(дверь № 2, как объяснено CMS) для window.onload
, изменения testprint
значение позже не влияет window.onload
ценность.
Дверь № 4 не переопределяет дверь № 2 (если, как вы сказали, вы не перемещаете ее в первый блок скрипта), потому что она находится в другом блоке скрипта, поэтому она анализируется после завершения первого блока.
Функция testprint является глобальной для страницы. testprint = function... назначает переменную, в которой я точно не уверен, но я понимаю, что она не добавлена в словарь таблицы функций, как первая.