Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Волшебные "функции" (https://javascript.ru/forum/misc/50237-volshebnye-funkcii.html)

petya 18.09.2014 00:17

Волшебные "функции"
 
Я до конца не понимаю этот вот тонкий механизм:
//код ниже противоречив, компилятор вытаскивает функцию наружу, хотя код внутри if не должен выполнятся:
;(function(){
if(false) function foo(){console.log("foo")}
console.log(foo) // [Function: foo]
})()

//а вот так противоречия уже нет:
;(function(){
if(false)var foo=function(){console.log("foo")}
console.log(foo) // undefined
})()

//а теперь внимание! Бомба!!!
// что с "use strict" что без:

foo()//foo
if(false)function foo(){console.log("foo")}

//И особенно непонятно вот это:

scope={msg: "Hello!"}
with(scope){
   function inner(){
      console.log(msg)
   }
}
inner()

// ошибка: msg не определен


scope={msg: "Hello!"}
with(scope){
   inner=function inner(){
      console.log(msg)
   }
}
inner()

//так норм


При этом, в ФФ вроде работает как ожидается, хотя все не проверял. Я понимаю, смутно, что эти все аномалии связаны с процессом компиляции, но что конкретно происходит, общая "логика", так сказать, до меня не доходит. В примерах с ифами еще более менее понятно: видимо, компилятор в первом проходе компилирует все function declarations, не обращая внимание на окружающий код, то что называется "подъем". А с with -- вообще задница.

Я вот еще что думаю. Если от function declaration (или как ее там) столько проблем, почему бы ее просто не убрать из языка? Трудности какие-то с этим, или что?

И вообще: НАХРЕН ОНА НУЖНА? ЗАЧЕМ ЕЕ ЗАПИЛИЛИ? Можно увидеть юзкейс, где без нее нельзя обойтись?

Erolast 18.09.2014 15:43

http://javascript.ru/unsorted/id
Почему бы не прикрутить на форум?

skrudjmakdak 18.09.2014 16:55

ты где этот код нарыл?

skrudjmakdak 18.09.2014 16:59

как то была тема про with, и говорили что ей не рекомендуется пользоваться

petya 18.09.2014 23:44

Цитата:

Сообщение от skrudjmakdak (Сообщение 331198)
как то была тема про with, и говорили что ей не рекомендуется пользоваться

Возможно (хотя спорно), но в данном случае, это отношения к делу не имеет. Здесь хрень заключена в кривизне реализации функций, а точней, обработки компилятором function declaration.

BETEPAH 19.09.2014 10:22

Цитата:

Сообщение от petya
десь хрень заключена в кривизне реализации функций, а точней, обработки компилятором function declaration.

Кривизной это кажется только тем, кто не знаком с основами объявления функций.
Каждый из вариантов объявлений имеет свое предназначение.
Function Declaration создают функцию ДО выполнения кода
Function Expression создают функцию когда до них доходит выполнение.
Поэтому комментарий "//а теперь внимание! Бомба!!!" отпал бы, если почитали бы учебник.

MallSerg 19.09.2014 11:20

И снова он )
яркий и запоминающийся почерк у человека ))

petya 19.09.2014 12:07

ВЕТЕРАН, какая разница, как реализована эта кривизна, она не перестает от этого быть таковой. Вы бы ради приличия привели бы юзкейс, как я просил, где function declaration действительно необходимы, где они оправдывают свое существование в языке. Читайте тему, прежде чем отвечать. Если не знаете ответа, не морочте людям голову, проходите мимо.

BETEPAH 19.09.2014 12:09

petya,
кривизна - это пытаться использовать что-то не по назначению. Используйте Function Expression там где нужно и не будет вопросов.

petya 19.09.2014 12:17

ВЕТЕРАН, С точки зрения пользователя языка, это именно кривизна дизайна, пользователь не обязан постоянно думать о своем коде с точки зрения тонкостей процесса компиляции. И главный вопрос, таки, остается открытым. Каково непосредственное НАЗНАЧЕНИЕ function declaration?

BETEPAH 19.09.2014 12:24

Цитата:

Сообщение от petya
И главный вопрос, таки, остается открытым. Каково непосредственное НАЗНАЧЕНИЕ function declaration?

объявление функции с доступом к ней в любом месте кода, как после объявления, так и до объявления.
Цитата:

Сообщение от petya
пользователь не обязан постоянно думать

поднятый вами вопрос не заставляет особо думать. Это на уровне механики. Нужен доступ к функции везде в области видимости - Function Declaration. Нужен доступ только после объявления - Function Expression.
Конструкции if не создают свою область видимости, поэтому код
foo()
if(false) function foo(){console.log("foo")}
не скрывает foo() в условии. Неужели это нужно разжевывать еще тщательнее? Если бы использовали Function Expression в этом коде, то функция не была бы объявлена, так как до нее не дошел бы код.
Извините, я потерял интерес к дальнейшему диалогу в этой ветке.

petya 19.09.2014 12:31

Цитата:

Сообщение от ВЕТЕРАН
Конструкции if не создают свою область видимости, поэтому код

Причем тут область видимости?
Практически во всех языках if обладает свойством ЛЕНИВОСТИ. ОН НЕ ДОЛЖЕН выполнять код, если условие не совпадает. В нашем же случае, семантически, он выполняет его или не выполняет в зависимости от погоды на марсе.

petya 19.09.2014 12:36

Цитата:

Сообщение от ВЕТЕРАН
объявление функции с доступом к ней в любом месте кода, как после объявления, так и до объявления.

Повторяю: ЗАЧЕМ РЕАЛЬНО это нужно?

petya 19.09.2014 12:39

Цитата:

Сообщение от ВЕТЕРАН
потерял интерес к дальнейшему диалогу в этой ветке.

Видимо потому, что по существу возразить нечего.

tsigel 19.09.2014 13:44

petya,
Рельно это нужно для того чтобы функция знала как её зовут и могла что-то с собой делать.

var trololo = function () {alert(arguments.callee.name)};
trololo()


function trololo() {alert(arguments.callee.name)}
trololo();


В чисто конкретном месте я использовал это для обертки над классами (чтобы в консоли у объектов были нормальные имена) и для модуля логгера, который мог вывести всю цепочку наследования моего класса
(Например он вывадил "Base.Module.UserEventManager")

petya 19.09.2014 14:18

tsigel, НЕТ

var trololo = function trololo () {console.log(arguments.callee.name)};
trololo()

tsigel 19.09.2014 14:34

Цитата:

Сообщение от petya (Сообщение 331356)
tsigel, НЕТ

var trololo = function trololo () {console.log(arguments.callee.name)};
trololo()

И что это должно значить?

trololo()
var trololo = function trololo () {console.log(arguments.callee.name)};
trololo()

petya 19.09.2014 14:39

tsigel,
Это значит, что имя функции это одно, а function declaration -- совершенно другое. Не по теме твой пример.

tsigel 19.09.2014 14:54

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

petya 19.09.2014 15:14

tsigel,

if(0)foo=function foo(){}
console.log(foo)//error

tsigel 19.09.2014 15:20

Точно, её же имя переменной перезатерает, глупость я сморозил.

petya 19.09.2014 15:24

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

function foo(){}
console.log(foo.name)
// foo

tsigel 19.09.2014 15:39

Да я не об этом

Erolast 19.09.2014 15:55

tsigel, да это же тролль, зачем ты его кормишь?


Часовой пояс GMT +3, время: 12:34.