Непонятная структура кода (новичковый вопрос)
На данном сайте есть статья по drag n drop
http://javascript.ru/ui/draganddrop в ней есть такая структура var dragMaster = (function() { // private методы и свойства var dragObject function mouseDown(e) { клик на переносимом элементе: начать перенос } function mouseMove(e){ if (dragObject) { отобразить перенос объекта } } function mouseUp(e){ if (dragObject) { конец переноса } } // public методы и свойства return { init: function() { // инициализовать контроллер document.onmousemove = mouseMove document.onmouseup = mouseUp }, makeDraggable: function(element){ // сделать элемент переносимым element.onmousedown = mouseDown } } }()) мне соверешенно непонятно зачем нужны скобки в перед словом function var dragMaster = =>(<= вот эта скобка function() и вот эти }()) в конце почему нельзя было написать? var dragMaster = function() {...код функции с вложенными функциями ...} но так не работает понятное дело :( Объясните плиз а то вообще не въеду. Только если можно подробно на уровне 1 класс 1 четверть. Статьи с сайта читал есть подозрения что надо курить замыкания. Но просто не понимаю что вообще это за конструкция var somthing = () и не функция вроде и не объект.. Объект же объявляется через фигурные скобки... Совсем не пойму |
Функция создается и сразу запускается.
|
Объясню на примере:
var ms=(new Date).getTime(); /*получить ms с 1970 года*/ Здесь скобки требуются для инициализации объекта в противном случае потребуетсяв к функции обращатся так var ms=(new Date);ms.getTime(); Подобная конструкция применяется для минимизации. var start=(new Date).getTime(); ... my code ... var ms=(new Date).getTime()-start; на выходе скорость выполнения участка кода. |
Проще говоря это одна из форм записи
|
var dragMaster = function() {...код функции с вложенными функциями ...}
можешь записать function dragMaster() {...код функции с вложенными функциями ...} |
Спасибо за ответы
|
Цитата:
вот эти два примера кода выдают разный результат var ms=(new Date).getTime(); alert("Time"+ms); Time1245469872876 а этот var ms=(new Date); ms.getTime(); alert("Time"+ms); выдает TimeSat Jun 20 2009 07:50:16 GMT+0400 Т.е понятно что в первом случае это кол-во миллисекунд а второе тоже самое но в отформатированном варианте. Но как то неаккуратненько. (c) Т.е нельзя сказать что вызовы абсолютно идентичны. :-? |
И еще сорри за занудство - но даже ести это как бы создание функции и сразу её запуск то зачем нужны скобки в конце кода
}()) в конце блока кода что они дают и зачем нужны? Без них кстати не работает. Почему нельзя было написать так }var dragMaster = (function() {...} ) А занудство тоже оправдано поскольку этап первоначльного въезжание в язык наиболее сложный так как непонятны многие базовые концепции, а еще в такой язык как с ЖаваСкрипт с исключительно путанным синатксисом. Похоже разработчки стандарта ЕСМА употребляли .. причем даже не траву а что то сильно потяжелее. Совершенно непонятно зачем было делать настолько сложный и запутанный язык для совершенно прикладных задач. Но это конечно имхо. |
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
|
LowCoder,
Материал: - "проблема": http://javascript.ru/ecma/part12#a-12.4 - решение: http://javascript.ru/ecma/part11#a-11.1.6 Скажу кратко (подробно, нужно потратить больше времени, текста и уже нужно иметь определённую теоретическую базу), чтобы не путать. Функции деляться на: - "Функция-Объявление" (FunctionDeclaration, FD); - "Функция-Выражение" (FunctionExpression, FE). Разницу сейчас тоже не буду описывать, т.к. это не важно в данном вопросе. Так вот, исходя из п.12.4: Цитата:
function a() {}(); Ошибка, т.к. неотличимо от "Функция-Объявление", которую нельзя вызвать сразу. Соответственно, нужно переделать выражение так, чтобы оно стало "Функция-Выражение". Самый простой способ - оператор группировки. (function a() {})(); Все ок, т.к. теперь это FE. Но основная суть данных конструкций, это создание "private"-переменных, которые будут доступны в наших функциях/объектах (а их мы вернём наружу и сможем использовать), но не будут загрязнять глобальное пространство. На простом синтетическом примере: var a = (function () { var b = 10; return b; })(); Создаём FE, и тут же её вызываем. Переменная "а" теперь 10, но переменная "b" не существует после вызова функции. Конструкию (function () { _наш_код_ })(); можно назвать инициализирующим пространством нашего объекта/библиотеки и т.д. Это пространство позволит вернуть наружу минимальный интерфейс, но (повторюсь) внутри себя иметь множество дополнительных, вспомогательных объектов, которые будут не видны снаружи: var a = (function () { // "private" var b = 10; function c() { return b + 10; } // интерфейс наружу return { test: c, q: b, z: function () { return c() + 10; } }; })(); // "a" инициализирован // надеюсь, понятно, что "а" - есть возвращённый объект, но не функция! // функция (FE) использовалась нами лишь для создания // "нашего пространства" и для возвращения этого объекта alert(a.test()); // 20 alert(a.q); // 10 alert(a.z()); // 30 Однако, ни "b", ни "c" не доступны посредством "а" напрямую. |
Цитата:
Цитата:
|
Цитата:
|
Большое спасибо, осбоенно Dmitry A. Soshnikov за ответы. Очень подробне и обстоятельные. Буду разбиратся дальше. Я писал много на С++ но JavaScript мне кажется "диким" :) языком после С++. Видимо я не могу пока понять практического смысла столь сложных конструкций. Буду разбиратся. Еще раз сапсибо.
|
Цитата:
Цитата:
Цитата:
|
Riim, в любом случае - в скобках - (...) - может быть только FE.
Цитата:
function initDragMaster() { // private методы и свойства var dragObject function mouseDown(e) { клик на переносимом элементе: начать перенос } function mouseMove(e){ if (dragObject) { отобразить перенос объекта } } function mouseUp(e){ if (dragObject) { конец переноса } } // public методы и свойства return { init: function() { // инициализовать контроллер document.onmousemove = mouseMove document.onmouseup = mouseUp }, makeDraggable: function(element){ // сделать элемент переносимым element.onmousedown = mouseDown } } } var dragMaster = initDragMaster(); Здесь есть основной минус - функция initDragMaster остаётся жить в глобальном пространстве, даже, когда она уже не нужна. Поэтому, обычно, для создания инициализующего скопа, и создают (анонимную) FE, которая выполнится сразу после создания и уничтожится (тем не менее, весь её внутренний контекст будет доступен в возвращённом объекте; но это уже тема про замыкания). Цитата:
|
Ну да - JavaScript кажется мне именно странным. Это очень точный термин. Из за очень большой свободы JavaScript кажется мне очень трудночитаемым языком в плане синтаксиса. Когда я первый раз увидел вложенные функции, обращения к переменным до их объявления, констрекции типа
var v= function() ... , добавление свойств и методов "по ходу дела" ну и еще ряд мелочей у меня волосы встали дыбом :) Надо конечно все это еще исследовать сильно. Я просто не понимаю зачем для веб програмирования, которое является чисто прикладной задачей был выбран такой сложный стандарт. Также и для АкшнСкрипт. Сделал на нем небольшой проект с нуля - измучился совершенно. По идее для таких задач должны были использоватся очень простые языки, что бы любой офисный работник мог бы освоить скажем типа ВизуалБейсик. Там все прямолинейно, логично, быстро и относительно безглючно. А тонкие ньюансы и навороченные фишки приводят имхо к сильнопутанному синтаксису и соответственно глюкам и трудноуловимым багам. Впрочем это мои первые и чисто субъективные впечатления. |
Цитата:
|
Цитата:
http://javascript.ru/ecma/part11#a-11.1.6 В скобках - уже expression. Всегда expression. Касательно функции, - FE. |
Цитата:
|
Цитата:
Касательно же функций (и изначального вопроса) - не обязательно функцию оборачивать в скобки, чтобы иметь возможность запустить. Например, здесь нет никаких скобок, но функция запускается: var a = { b: function () { return 10; }() }; alert(a.b); // 10 Почему? Потому что парсер уже распознал функцию как FE. В случае же описания в начале темы - есть неоднозначность - путаница с FD, поэтому парсер выдаёт ошибку. Когда же мы помещаем её в оператор группировки, внутренности которого всегда являются expression'ом (а что ещё, по Вашему, там может быть? ;)), парсер однозначно определят функцию, как FE, и выполняет. |
Цитата:
|
Цитата:
|
(function(a,b){..код..})(a,b)
анонимная функция которая запустится сразу же, без объявления названий функций и без использования переменной. это удобно при инициализации неких задач а то, что там скобки, то это вопросы к разработчикам языка. думаю это вопрос не столько удобства или неудобства, это вопрос технического характера. |
Часовой пояс GMT +3, время: 01:08. |