JavaScript: Чем «функция onload () {}» отличается от «onload = function () {}»? - PullRequest
20 голосов
/ 30 ноября 2009

В ответах на этот вопрос мы читаем, что function f() {} определяет имя локально, а [var] f = function() {} определяет его глобально. Это имеет смысл для меня, но между этими двумя объявлениями есть странное поведение, отличающееся от других.

Я сделал HTML-страницу со скриптом

onload = function() {
    alert("hello");
}

и все заработало как положено. Когда я изменил его на

function onload() {
    alert("hello");
}

ничего не произошло. (Firefox все еще запускал событие, но WebKit, Opera и Internet Explorer этого не сделали, хотя, честно говоря, я понятия не имею, что является правильным.)

В обоих случаях (во всех браузерах) я мог убедиться, что функции window.onload и onload были установлены. В обоих случаях глобальный объект this устанавливается в окно, и, независимо от того, как я пишу объявление, объект window получает свойство просто отлично.

Что здесь происходит? Почему одна декларация отличается от другой? Является ли это причудой языка JavaScript, DOM или взаимодействия между ними?

Ответы [ 6 ]

4 голосов
/ 08 апреля 2010

Эти два фрагмента объявляют функцию в текущей области, называемую «onload». Связывание не выполняется.

function onload() { ... }

.

var onload = function() { ... }

Этот фрагмент назначает функцию свойству / переменной / полю с именем «onload» в текущей области:

onload = function() { ... }

Причиной, по которой Firefox выполнил привязку и вызвал событие onload для 1-го фрагмента, а другие - нет, может быть потому, что сам Firefox Chrome (его пользовательский интерфейс) написан и автоматизирован с использованием JavaScript - вот почему он такой гибкий и легко написать расширения на нем. Каким-то образом, когда вы таким образом объявили локально-ориентированную функцию onload, Firefox «заменил» реализацию window (скорее всего, локальный контекст в то время) на onload (в то время пустую функцию или не определено), когда другие браузеры правильно «помещают» песочницу в другую область видимости (скажем, global или что-то в этом роде).

4 голосов
/ 30 ноября 2009

Многие люди правильно указывают на глобальную / локальную разницу между ( ОБНОВЛЕНИЕ: эти ответы в основном были удалены их авторами )

var x = function() {

и

function x() {

Но это на самом деле не отвечает на ваш конкретный вопрос, поскольку вы на самом деле не делаете первый из них.

Разница между ними в вашем примере:

// Adds a function to the onload event
onload = function() {
    alert("hello");
}

Принимая во внимание

// Declares a new function called "onload"
function onload() {
    alert("hello");
}
1 голос
/ 01 декабря 2009

Вот что я думаю, основываясь на полезных комментариях Тима Дауна и краткой беседе с Джонатаном Пенном:

Когда интерпретатор JavaScript присваивает свойству window.onload, он обращается к объекту, который ему дал браузер. Установщик, который он вызывает, замечает, что свойство называется onload, и, таким образом, уходит к остальной части браузера и связывает соответствующее событие. Все это выходит за рамки JavaScript - скрипт просто видит, что свойство установлено.

Когда вы пишете объявление function onload() {}, сеттер не вызывается так же. Поскольку объявление приводит к тому, что назначение происходит в разбор времени, а не времени оценки, интерпретатор сценария продолжает работу и создает переменную, не сообщая браузеру; или же объект окна не готов к приему событий. Как бы то ни было, браузер не получает возможности увидеть назначение, как это происходит, когда вы пишете onload = function() {}, что проходит через обычную процедуру установки.

0 голосов
/ 08 апреля 2010

Самое простое объяснение:

function aaaaaaa(){

Может быть использовано до объявления:

aaaaaaa();
function aaaaaaa(){

}

Но это не работает:

aaaaaaa();
aaaaaaa=function(){

}

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

0 голосов
/ 08 апреля 2010

Это приводит к ошибке:

foo();
var foo = function(){};

Это не:

foo();
function foo(){}

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

0 голосов
/ 30 ноября 2009
var onload = function() {
    alert("hello");
}

Также объявит это локально.

Предлагаю вам прочитать эту очень полезную статью: http://kangax.github.io/nfe/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...