Подтвердить что ты не робот

Почему JavaScript не требует функции main()?

Многие языки программирования требуют специальной пользовательской функции, которая знаменует начало исполнения. Например, в C эта функция всегда должна иметь имя main(). В JavaScript, однако, такая функция не требуется.

Какова логическая причина отсутствия такой специальной функции верхнего уровня в JavaScript? Я знаю, что это какой-то теоретический вопрос, но я не могу найти ответ в Интернете.

4b9b3361

Ответ 1

Потому что весь блок кода фактически один большой main. В JavaScript глобальный код может иметь все код функции конструкций, который может иметь, и имеет ступенчатое выполнение, как и функции. Фактически, когда JS-движок обрабатывает блок кода в целом, он выполняет почти то же самое, что и при обработке вызова функции. См. Разделы спецификации 10.4.1 ( "Ввод глобального кода" ) и 10.4.3 ( "Ввод кода функции" ) и обратите внимание на то, насколько они похожи.

C не позволяет выполнять пошаговый код на глобальном уровне (у вас могут быть всевозможные инициализаторы, и они могут выглядеть как поэтапно, но это другая тема). И поэтому C требуется явная точка входа (main). В JavaScript точкой входа является начало кода.


Что касается вашего вопроса ниже о том, является ли глобальный код последовательным. Ответ - да, это точно так же, как код в функции. Итак:

var x, y, z;
x = 1;
y = 2;
z = x + y;
alert("z is " + z);

... будет предупреждать "z is 3". Код выполняется последовательно, сверху вниз.

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

  • Имя любой переменной, объявленной с помощью var, добавляется в область (со значением undefined) перед выполнением любого поэтапного кода. (Подробнее: Плохо, неправильно понято var)

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

Так, например, в этом исходном тексте:

var x;
x = 1;
foo();

function foo() {
}

объявления

var x;
function foo() {
}

а пошаговый код

x = 1;
foo();

Сначала обрабатываются декларации. Вот почему работает вызов foo. (Эти же правила применяются к исходному тексту внутри функций.) Эта обработка объявлений перед чем-либо еще иногда называется "подъемом", потому что декларации в некотором смысле отрываются от их местоположения в исходном тексте и перемещаются в самом начале. Я предпочитаю думать об этом как о двух проходах через источник: первый проход делает объявления, второй выполняет поэтапный код.

(Боковое примечание: объявление переменной более одного раза в той же области вполне законно [хотя и бессмысленно]. Объявление двух функций с тем же именем также является законным, последнее объявление переопределяет предыдущее.)

(В примечании 2: ES2015 [ES6] введены объявления let и const переменных, которые ведут себя несколько иначе, чем var. Вы не можете объявить переменную дважды с ними, у них есть область блока, и вы не могут использовать переменную до утверждения, где она была объявлена. Поэтому они в основном не подняты [есть что-то вроде подъема в том, что они препятствуют доступу к теневой переменной в области сложения еще до let x или любой другой строки ].)


Подробнее и, возможно, немного технически:

var

Если var происходит до запуска поэтапного кода, вам может быть интересно:

var x = 1;

Это происходит до поэтапного кода или как часть его? Ответ заключается в том, что на самом деле это просто сокращение двух совершенно разных вещей:

var x;
x = 1;

Часть var x; выполняется перед поэтапным кодом, часть x = 1; является ступенчатым кодом и выполняется, когда мы достигаем ее в последовательности. Итак:

alert(x); // "undefined" -- there **is** a variable `x`; it has the value `undefined`
var x = 1;
alert(x); // "1" -- now `x` has the value `1`

Объявление функций

JavaScript имеет две разные, но очень похожие вещи: объявления функций и выражения функций. Вы можете указать, какая из них связана с тем, используете ли вы результирующую функцию как часть выражения, в котором она определена.

Здесь объявление функции:

function foo() {
}

Это все выражения функций (мы используем полученное значение функции как часть выражения, в терминологии информатики функция используется как правое значение):

// 1: Assigning the result to something
var x = function() {
};

// 2: Passing the result into a function
bar(function() {
});

// 3: Calling the function immediately
(function(){
})();

// 4: Also calling the function immediately (parens at end are different)
(function(){
}());

// 5: Also calling the function immediately
!function(){
}();

// 6: Syntax error, the parser needs *something* (parens, an operator like ! or
// + or -, whatever) to know that the `function` keyword is starting an *expression*,
// because otherwise it starts a *declaration* and the parens at the end don't make
// any sense (and function declarations are required to have names).
function(){
}();

Правило состоит в том, что объявления функций обрабатываются до начала поэтапного кода. Выражения функции, как и все другие выражения, обрабатываются там, где они встречаются.

Одно заключительное примечание: это выражение функции с именем:

var f = function foo() {
};

Мы используем его как правое значение, поэтому мы знаем это выражение; но у него есть имя, подобное объявлениям функций. Это совершенно правильный и законный JavaScript, и то, что он хотел сделать, - создать функцию с правильным именем (foo) как часть поэтапного кода. Имя функции не добавляется в область (как это было бы, если бы это было объявление функции).

Однако вы не увидите названные функциональные выражения в очень многих местах, потому что JScript (движок Microsoft JavaScript) получает их ужасно и совершенно неправильно, создавая две отдельные функции в два разных раза.

Ответ 2

Как и большинство языков сценариев, Javascript сначала выполняет глобальный код, то есть код, который не является частью какой-либо функции. На самом деле, очень немногие языки имеют явную главную функцию, поэтому нет ничего странного в поведении Javascript.

В отличие от скомпилированных языков, в Javascript исходный код программы существует во время выполнения, и он может иметь код, который управляет другим кодом. Например, объявления функций на самом деле исполняемые операторы, вы не "заявляете" что-либо в JS, а скорее назначаете кусок кода переменной. В этом смысле весь код JS верхнего уровня выполняется последовательно:

Однако объявления функций и инструкции var перемещаются в начало области ( " hoisted" ). поэтому нет, JS-код не выполняется последовательно.

Ответ 3

JavaScript управляется событиями, программа, написанная на JavaScript, не имеет начала и конца. Вы можете сравнить его с любым инструментарием пользовательского интерфейса для ПК, где вы обрабатываете нажатия кнопок и нажатия клавиш, но при инициализации программы нет очевидного main.

Например, есть событие window.onload, которое запускается при загрузке страницы и которое вы можете обрабатывать.

Ответ 4

на языке сценариев код выполняется из первой строки в файле до конца, как если бы он был введен в интерпретатор. (это не исключает синтаксический анализ и компиляцию кода, если этот процесс не влияет на описанную денотационную семантику.)

Ответ 5

Вы уже знаете ответ

В JavaScript, однако, такая функция не требуется!

JavaScript - это язык сценариев, в то время как C необходимо скомпилировать.