в этом примере в статье о функциях MDN: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Functions
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<script src = "./script/first.js"></script>
<script src = "./script/second.js"></script>
<script>
greeting();
</script>
<title>Document</title>
</head>
<body>
</body>
</html>
// first.js
const name = "Chris";
function greeting() {
alert(`Hello ${name}: welcome to our company.`);
}
// second.js
const name = "Zaptec";
function greeting() {
alert(`Our company is called ${name}.`);
}
почему выполняется первая функция приветствия, но если я изменю имя константы на просто имя
// second.js
name = "Zaptec";
function greeting() {
alert(`Our company is called ${name}.`);
}
выполняется второй метод приветствия?
насколько я понимаю, во втором случае функция приветствия в Second.js поднимается наверх, поэтому она переопределяет первый метод приветствия до того, как будет выдано исключение и скрипт остановлен, но почему этого не происходит в первом случае?
@Keith: На самом деле, я думаю, что здесь все еще есть подъем, потому что в противном случае он должен иметь тот же эффект даже без const, поскольку переназначение name все равно не удастся, поскольку name является const. Однако при подъеме сначала выполняется второе определение greeting (успешно), за которым следует неудачное переназначение. В случае, если в обеих строках есть const, этого не происходит, поскольку тогда ошибка будет SyntaxError, а не TypeError, что происходит на этапе синтаксического анализа, а не на этапе выполнения.
@CherryDT То, что происходит, не имеет ничего общего с подъемом, поместите все в один тег сценария, все будет иметь больше смысла. Я думаю, что ОП сбивает с толку то, как загружаются сценарии.
@Keith Я думаю, дело в том, почему первый случай (обе строки с const) приводит к Hello Chris: welcome to our company, а второй случай (первая строка с const, а вторая без) приводит к Our company is called Chris. И ответ в том, что в первом случае код второго файла вообще не запускается (из-за синтаксической ошибки), а во втором случае он анализируется, а затем начинает выполняться, сначала выполняя определение поднятой функции (даже несмотря на то, что оно физически ниже задания), затем задание, которое теперь завершается с ошибкой времени выполнения.
@CherryDT Обратите внимание, как это говорит ОП в ответ на ваши вопросы -> the two cases both throw an exception so they should both stop the script but one of them doesn't. IOW: выполнение двух тегов сценария один за другим не работает так же, как один тег сценария со всем кодом. Для одного сценария не имеет значения, какая ошибка выдается, сценарий завершится неудачей и остановится как OP. ожидал.
@Keith Но в этом-то и дело. Почему второе исключение не мешает второму определению greeting переопределить первое? Из-за подъема. И этого не происходит с первым исключением, поскольку синтаксические ошибки возникают на этапе синтаксического анализа, прежде чем произойдет подъем. (Попробуйте: измените function greeting () на greeting = function () во втором скрипте, чтобы это было уже не определение функции, а присвоение функционального выражения и, следовательно, больше не поднималось, и оно внезапно снова начало вести себя, как в первом случае.)
@CherryDT Да, я понимаю эту часть. Я также имел в виду, почему ОП ожидал, что в обоих случаях сценарии в целом потерпят неудачу, вы указываете причину, по которой второй анализирует, и я согласен с этим. Моя точка зрения заключалась не в том, что подъема не произошло, а в том, почему поведение в обоих случаях не останавливает все. Надеюсь, это имеет смысл. Я думаю, что оба ответа, возможно, отвечают на разные части вопроса... :)
@CherryDT Я не знал, что синтаксические ошибки обрабатываются таким образом в JS, я думал, что они действуют как любое другое исключение, поэтому останавливают выполнение только тогда, когда они выполняются. Я новичок в JS (начал изучать его неделю назад). Не могли бы вы, ребята, порекомендовать мне хороший бесплатный или платный источник, например книгу, для более глубокого изучения JS?
@mahmoudmirghani Это логично, если подумать, какой может быть альтернатива. Что, если синтаксическая ошибка возникла из-за случайного {, расположенного перед определением функции?
Я думал, что JS попытается выяснить что-то, как всегда, даже если есть синтаксическая ошибка. но да, это моя вина, что я этого не заметил. в любом случае спасибо.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Потому что первая ошибка — это SyntaxError, которая возникает перед подъемом, а вторая ошибка — это TypeError, которая происходит после подъема.
В первом случае получается SyntaxError: Identifier 'name' has already been declared, вызванный второй строкой const name = ....
Если вы удалили оба ключевых слова const, это «работает», но фактически меняет глобальную переменную window.name.
Однако, если вы удалите только второе ключевое слово const, вы получите другую ошибку: TypeError: Assignment to constant variable., и действительно, оно использует второе определение greeting, но с первым name!
Вы можете задаться вопросом, почему второй случай ведет себя иначе? Это потому, что SyntaxError происходит во время анализа файла (только чтения, но еще не выполнения). Он терпит неудачу в первой строке и прекращает обработку остальной части файла. С другой стороны, TypeError происходит во время выполнения, во время выполнения. В этот момент подъем уже состоялся! Второй greeting уже был перемещен вверх, и новое определение функции уже было выполнено, переопределив предыдущее. Только после этого const name = ... был выполнен и потерпел неудачу.
Резюме:
Первый случай (const в обоих файлах): второй файл не удается проанализировать с помощью SyntaxError. В этом файле ничего не выполняется.
Второй случай (const только в первом файле): второй файл удалось проанализировать, greeting поднимается. Начинается выполнение, применяется поднятое greeting определение, затем const name = ... не выполняется с TypeError и дальнейшее выполнение останавливается (но там все равно больше нечего выполнять).
оба случая выдают исключение, поэтому оба должны остановить скрипт, но один из них этого не делает (второй случай)
@mahmoudmirghani Неудачная загрузка скрипта не останавливает загрузку следующих или предыдущих скриптов. Примечание: вы наблюдаете не Javascript, а просто способ загрузки скриптов. Если бы все было в одном скрипте, то переобъявление const потребовало бы остановил все.
Потому что второй скрипт не загружается из-за переобъявления
const.. Никакого отношения к поднятию.