JavaScript:Чем «function onload() {}» отличается от «onload = function() {}»?

StackOverflow https://stackoverflow.com/questions/1818501

  •  10-07-2019
  •  | 
  •  

Вопрос

В ответах на этот вопрос, мы это читаем 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 или взаимодействия между ними?

Это было полезно?

Решение

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

function onload() { ... }

.

var onload = function() { ... }

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

onload = function() { ... }

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

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

Многие люди правильно указывают на глобальную/локальную разницу между (ОБНОВЛЯТЬ:Эти ответы в настоящее время в основном удалены их авторами.)

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");
}

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

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

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

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

function aaaaaaa(){

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

aaaaaaa();
function aaaaaaa(){

}

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

aaaaaaa();
aaaaaaa=function(){

}

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

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

Будет также объявлять это локально.

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

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

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

Это не так:

foo();
function foo(){}

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top