Неоднозначное объявление функции в JavaScript

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

say();

function say()
{
    alert("say");
}

Предописание работало, и всплывающее окно "говорят"

На противоположном

say();

say = function()
{
    alert("say");
}

не работал, хотя это также объявило функциональный объект

Если мы объявляем функцию и повторно объявляем что впоследствии:

function say()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

Я добрался, "говорят" вместо, "говорят". Это - удивление!

Хорошо. Кажется, что только последнее объявление функции работает. Тогда позволяет, объявляют функциональный объект сначала и затем "регулярную" функцию:

say = function()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

say();

Другое удивление, это было, "говорят" сопровождаемый, "говорят". "Обычное" объявление функции не работало вообще!

Существует ли объяснение всех их? И, если "обычное" объявление функции действительно настолько "хрупко" и может быть легко переопределением функциональным объектом с тем же именем, я должен избегать этого?

Другой вопрос: только с форматом функционального объекта то предописание становится невозможным? Там какой-либо путь состоит в том, чтобы "моделировать" это в JavaScript?

11
задан Wei Xiang 15 January 2010 в 15:30
поделиться

4 ответа

say();

function say()
{
    alert("say");
}

Здесь переводчик извлекает определение , скажем () , когда он называется и выполняет его.

say();

say = function()
{
    alert("say");
}

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

function say()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

Здесь , скажем, определяется, а затем переопределяется - последнее определение выигрывает.

say = function()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

say();

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

Но если у вас было

say();

say = function()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

, то вы получите «сказать», а затем «говори».

1
ответ дан 3 December 2019 в 12:05
поделиться

Вы можете ожидать применения ваших функций определения в порядке. Затем все ваши не методические линии кода будут выполнены в порядке, включая присвоение объектов функциональных объектов. Это объясняет каждый из ваших примеров. Это интересная проблема, хотя. Вы действительно не можете назначить объект функциональности после того, как пытается вызвать его и ожидать его на работу. Однако определение функции, которое следует за исполняемым кодом, фактически применяется первым.

0
ответ дан 3 December 2019 в 12:05
поделиться

JavaScript работает так, как это работает:

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

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

Что вы испытываете, что если вы дважды объявляете функцию, последний будет использоваться всей приложением. Это ваш третий пример.

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

Если бы вы будете Redeclare , скажем во время выполнения, то есть поменяйте порядок деклараций в вашем последнем примере, то вы увидите два разных оповещения, которые вы ожидаете:

say(); //speak, the global function

function say() {
  alert('speak');
}

var say = function() {
  alert('say');
}

say(); //say, the declared local variable
2
ответ дан 3 December 2019 в 12:05
поделиться

Это всегда хорошая идея, вызывая функцию позже, хотя JavaScript работает так.

Большинство языков не будут работать таким образом, вместо этого делают это.

function say(){
    alert("say");
}

say();

ИЛИ

say = function(){
    alert("say");
}

say();

или

(function(){
    alert("say");
})();
0
ответ дан 3 December 2019 в 12:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: