Переобъявление и подъем функции JavaScript

в этом примере в статье о функциях 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 поднимается наверх, поэтому она переопределяет первый метод приветствия до того, как будет выдано исключение и скрипт остановлен, но почему этого не происходит в первом случае?

Потому что второй скрипт не загружается из-за переобъявления const.. Никакого отношения к поднятию.

Keith 25.06.2024 23:07

@Keith: На самом деле, я думаю, что здесь все еще есть подъем, потому что в противном случае он должен иметь тот же эффект даже без const, поскольку переназначение name все равно не удастся, поскольку name является const. Однако при подъеме сначала выполняется второе определение greeting (успешно), за которым следует неудачное переназначение. В случае, если в обеих строках есть const, этого не происходит, поскольку тогда ошибка будет SyntaxError, а не TypeError, что происходит на этапе синтаксического анализа, а не на этапе выполнения.

CherryDT 25.06.2024 23:13

@CherryDT То, что происходит, не имеет ничего общего с подъемом, поместите все в один тег сценария, все будет иметь больше смысла. Я думаю, что ОП сбивает с толку то, как загружаются сценарии.

Keith 25.06.2024 23:16

@Keith Я думаю, дело в том, почему первый случай (обе строки с const) приводит к Hello Chris: welcome to our company, а второй случай (первая строка с const, а вторая без) приводит к Our company is called Chris. И ответ в том, что в первом случае код второго файла вообще не запускается (из-за синтаксической ошибки), а во втором случае он анализируется, а затем начинает выполняться, сначала выполняя определение поднятой функции (даже несмотря на то, что оно физически ниже задания), затем задание, которое теперь завершается с ошибкой времени выполнения.

CherryDT 25.06.2024 23:21

@CherryDT Обратите внимание, как это говорит ОП в ответ на ваши вопросы -> the two cases both throw an exception so they should both stop the script but one of them doesn't. IOW: выполнение двух тегов сценария один за другим не работает так же, как один тег сценария со всем кодом. Для одного сценария не имеет значения, какая ошибка выдается, сценарий завершится неудачей и остановится как OP. ожидал.

Keith 25.06.2024 23:25

@Keith Но в этом-то и дело. Почему второе исключение не мешает второму определению greeting переопределить первое? Из-за подъема. И этого не происходит с первым исключением, поскольку синтаксические ошибки возникают на этапе синтаксического анализа, прежде чем произойдет подъем. (Попробуйте: измените function greeting () на greeting = function () во втором скрипте, чтобы это было уже не определение функции, а присвоение функционального выражения и, следовательно, больше не поднималось, и оно внезапно снова начало вести себя, как в первом случае.)

CherryDT 25.06.2024 23:27

@CherryDT Да, я понимаю эту часть. Я также имел в виду, почему ОП ожидал, что в обоих случаях сценарии в целом потерпят неудачу, вы указываете причину, по которой второй анализирует, и я согласен с этим. Моя точка зрения заключалась не в том, что подъема не произошло, а в том, почему поведение в обоих случаях не останавливает все. Надеюсь, это имеет смысл. Я думаю, что оба ответа, возможно, отвечают на разные части вопроса... :)

Keith 25.06.2024 23:32

@CherryDT Я не знал, что синтаксические ошибки обрабатываются таким образом в JS, я думал, что они действуют как любое другое исключение, поэтому останавливают выполнение только тогда, когда они выполняются. Я новичок в JS (начал изучать его неделю назад). Не могли бы вы, ребята, порекомендовать мне хороший бесплатный или платный источник, например книгу, для более глубокого изучения JS?

mahmoud mirghani 26.06.2024 00:12

@mahmoudmirghani Это логично, если подумать, какой может быть альтернатива. Что, если синтаксическая ошибка возникла из-за случайного {, расположенного перед определением функции?

CherryDT 26.06.2024 07:12

Я думал, что JS попытается выяснить что-то, как всегда, даже если есть синтаксическая ошибка. но да, это моя вина, что я этого не заметил. в любом случае спасибо.

mahmoud mirghani 26.06.2024 13:29
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
10
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Потому что первая ошибка — это 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 и дальнейшее выполнение останавливается (но там все равно больше нечего выполнять).

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

mahmoud mirghani 25.06.2024 23:07

@mahmoudmirghani Неудачная загрузка скрипта не останавливает загрузку следующих или предыдущих скриптов. Примечание: вы наблюдаете не Javascript, а просто способ загрузки скриптов. Если бы все было в одном скрипте, то переобъявление const потребовало бы остановил все.

Keith 25.06.2024 23:12

Другие вопросы по теме