2012-04-02 2 views
17

Если я запускаю функцию ниже до определения его, я получаю эту ошибку ...Должна ли быть определена функция Javascript до ее вызова?

Uncaught ReferenceError: openModal is not defined 

запустить затем определить

$(document).ready(function() { 

    delay(openModal, 2000); 

    delay = function (f, t) { 
     setTimeout(function() { 
      f(); 
     }, t); 
    }; 

    openModal = function() { 
     $('#modal-box').css({ 
      left: $(window).width()/2 - $('#modal-box').width()/2, 
      top: $(window).height()/2 - $('#modal-box').height()/2 
     }); 
     $('#modal-box').show(); 
     $('#modal-mask').show(); 
    }; 

}); 

Теперь, если я определить функцию первого, а затем вызвать его это работает ... У меня есть опыт работы с PHP, поэтому я привык к возможности доступа к функциям во всем мире, я делаю что-то неправильно или все функции должны быть определены до их использования?

$(document).ready(function() { 

    delay = function (f, t) { 
     setTimeout(function() { 
      f(); 
     }, t); 
    }; 

    openModal = function() { 
     $('#modal-box').css({ 
      left: $(window).width()/2 - $('#modal-box').width()/2, 
      top: $(window).height()/2 - $('#modal-box').height()/2 
     }); 
     $('#modal-box').show(); 
     $('#modal-mask').show(); 
    }; 

    delay(openModal, 2000); 

}); 
+0

Это все, то есть вы объявили идентификатор 'openModal' (в отличие от его определения) выше этой сферы? например 'var openModal;' – Rup

+2

Связанный: http://stackoverflow.com/questions/261599/why-can-i-use-a-function-before-its-defined-in-javascript – TJHeuvel

+0

@Rup, который является впервые openModal используется – JasonDavis

ответ

32

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

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

$(document).ready(function() { 

    delay(openModal, 2000); 

    function openModal() { 
     $('#modal-box').css({ 
      left: $(window).width()/2 - $('#modal-box').width()/2, 
      top: $(window).height()/2 - $('#modal-box').height()/2 
     }); 
     $('#modal-box').show(); 
     $('#modal-mask').show(); 
    }; 

}); 

(Обратите внимание на разницу в объеме, хотя, когда вы. создайте переменную openModal неявно, просто используя ее, она будет создана в глобальной области действия и будет доступна для всего кода. Когда вы объявляете функцию внутри другой функции, она будет доступна только внутри этой функции. переменная, локальная для этой функции, с использованием var openModal = function() {.)

6

Переместить определение функции за пределы блока document.ready, и все будет работать так, как вы ожидаете. В javascript (как на большинстве языков) вы должны определить функцию или переменную, прежде чем ссылаться на нее.

В вашем первом примере вы ссылаетесь openModal на звонок delay(), но javascript не знает, что такое openModal.

openModal = function() { 
    $('#modal-box').css({ 
     left: $(window).width()/2 - $('#modal-box').width()/2, 
     top: $(window).height()/2 - $('#modal-box').height()/2 
    }); 
    $('#modal-box').show(); 
    $('#modal-mask').show(); 
}; 

$(document).ready(function() { 
    delay(openModal, 2000); 
}); 

редактировать:

TJHeuvel указывает на то, что function делает некоторые хитрости, чтобы определить функции, прежде чем что-либо еще выполняется в том же блоке: Why can I use a function before it's defined in Javascript?

+4

Какой смысл определять функцию снаружи? * "вы должны определить функцию [...], прежде чем ссылаться на нее" *: Не обязательно. Поскольку функции * декларации * поднимаются, вы можете определить их где угодно, а другой код в текущей области может вызвать его. Только функциональные * выражения * могут быть вызваны после их назначения. –

+0

Обратите внимание, что то, что указывает TJHeuvel, не применяется, когда вы назначаете функцию переменной. Даже если сам объект функции создается при анализе кода, он присваивается переменной во время выполнения. – Guffa

-1

In shor т да вы должны определить его, прежде чем использовать функцию, но вы можете использовать функцию SetTimeout для вашей задержки, которая принимает строку в качестве кода exectute:

$(document).ready(function() { 

    setTimeOut('openModal()', 2000); 

    openModal = function() { 
     $('#modal-box').css({ 
      left: $(window).width()/2 - $('#modal-box').width()/2, 
      top: $(window).height()/2 - $('#modal-box').height()/2 
     }); 
     $('#modal-box').show(); 
     $('#modal-mask').show(); 
    }; 

}); 

это будет работать как функция не не вызывается до после его определения.

+2

Ваше первое предложение не работает, так как на данный момент вы вызываете 'delay (openModal, 2000)', 'openModal' все еще держит ссылку на пустую функцию. Реальная функция назначается только потом, но она не влияет на уже пройденное значение. Ваше второе предложение работает «по ошибке». Поскольку 'openModal' не объявляется с помощью' var', он является глобальным. Но как только вы объявите его правильно с помощью 'var', он больше не будет работать, поскольку' setTimeout' оценивает строки в глобальной области (и 'openModal' будет локальным для обработчика готовых событий). –

+0

ОК спасибо. отредактированный – Richard

1

Я бы сказал, ДА. Перед вызовом всегда должна быть определена функция. Но некоторые функции могут вызываться (так называемая) до того, где они были определены (грузоподъемная)

два различных типа функций, которые я хочу написать о которых:

Функция Expression & Функция торможение

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

let lastName = function (family) { 
console.log("My last name is " + family); 
};   
let x = lastName("Lopez"); 

Это, как вы можете написать в ES6:

lastName = (family) => console.log("My last name is " + family); 
x = lastName("Lopez"); 

2- Функции торможения: Функции, объявленные с помощью следующего синтаксиса не выполняется немедленно. Они «сохраняются для последующего использования» и будут выполняться позже, когда они будут вызваны (вызваны). Этот тип функций работает, если вы вызываете их ПЕРЕД или ПОСЛЕ того, где они были определены. Если вы вызываете функцию замедления до того, где она была определена - Подъем - работает правильно.

function Name(name) { 
    console.log("My cat's name is " + name); 
} 
Name("Chloe"); 

Подъемно пример:

Name("Chloe"); 
function Name(name) { 
    console.log("My cat's name is " + name); 
} 
Смежные вопросы