Есть случайное такое хобби — программирование на JavaScript.
Недавно возник у меня глобальный вопрос:
Как часто JS программисты задумываются над [function statement]?
На днях решил поискать в яднексе, как-то, кажется,
попадалась на глаза книжка «Как перестать программировать и начать жить», нашел.
«Cейчас не об этом» и «Нет! Мы не будем полагаться на случай!».
(© – «Ирония судьбы, или «с легким п��ром»!»)
Что Мы все о нем знаем:
function My_Function_Name([parametrs]) { [Operators]; }
Почти все знают еще это:
My_Function_Name = function ([parametrs]) { [Operators]; }
Большинство знает про важность этого:
var My_Function_Name = function ([parametrs]){ [Operators]; }
И в частности этого:
function () { var My_Function_Name = function ([parametrs]){ [Operators]; } })()
Некоторые особенные создания даже делают так:
(function (){ var My_Function_Name = new function ([parametrs]) { [Operators]; } })()
и, может быть в этой конструкции даже есть не совсем очевидный какой-нибудь смысл…
Пусть, допустим, есть:
Функция, которая что-то делает.
например так:
var mix = function (id){ return document.getElementById(id); }
:) — типа она сильно упрощает жизнь.
и к ней, приложено, например:
mix.s = function (id){ mix(id).style; };
Сразу скажу, чтобы потом не было вопросов:
я знаю про JQuery, Prototype, Script.Aculo.us и т.п.
Я понимаю, что это гораздо удобней чем писать своё.
Смысл статьи не в том, чтобы писать framework.
Решили немножко улучшить функционал, вот так:
mix.T = function(id, par) { if (par) { mix.s(id).top = par; } else { return parseInt(mix.s(id).top); } } mix.L = function(id, par) { if (par) { mix.s(id).left = par; } else { return parseInt(mix.s(id).left); } } mix.W = function(id, par) { if (par) { mix.s(id).width = par; } else { return parseInt(mix.s(id).width); } } mix.H = function(id, par) { if (par) { mix.s(id).height = par; } else { return parseInt(mix.s(id).height); } }
Банально, не правда ли?
Это всё для примера, так что не ругайтесь.
Теперь вернемся немного назад, к безымянным функциям (замыканиям).
(function() { [Operators]; })()
Нелепая попытка сделать пару примеров «на засыпку»:
- мы знаем про оператор new,
- мы знаем про связку new и Function(),
- зачем могут быть нужны «безымянные» переменные?
Персональное безумие началось с «Вики-англичанки»: статя
про JavaScript.
Там внизу есть Syntax and semantics — замечательный пример.
После этого «щелкнула» известная многим
набла.
И, главное — последующий
тред.
Здесь они почти ни при чём, но после «Вики» были именно они.
Из этого вышел вот такой бред, очевидно, что переменные не совсем безымянные:
(function() { mix.init = false; var ag = arguments; //just a sample alert(ag[2]); var prepareFucntionArgs = function(el) { var ra = el; if ((el == "i") || (el == "")) { ra = ["id"]; } if (el == "p") { ra = ["id", "par"]; } return ra; } var prepareFunctionBody = function(el) { var str = el[1] .replace(/_tp/g, "_i _m._a_p _e _r _m._a; }") .replace(/_tr/g, "_i _s._a_p _e _r _I_s._a); }") .replace(/_i/g, "if (par){ ") .replace(/_I/g, " parseInt(") .replace(/_e/g, " }else{ ") .replace(/_r/g, " return ") .replace(/_p/g, " = par; ") .replace(/_m./g, "mix(id).") .replace(/_s./g, "mix.s(id)."); if (el[2]) { str = str.replace(/_a/g, el[2]); } return str; } for (var i in ag[0]) { // parsing "0" arguments array (function() { try { var a = ag[0][i]; var pf_A = prepareFucntionArgs(a[0]); var pf_B = prepareFunctionBody(a); mix[i] = new Function(pf_A, pf_B); } catch (e) { alert(e); alert("" + i + "\n" + pf_A + "\n" + pf_B); } finally {} })(); }; for (var i in ag[1]) { mix[i] = ag[1][i]; }; })({ s: ["", "_r _m.style;"], cn: ["p", "_tp", "className"], T: ["p", "_tr", "top"], L: ["p", "_tr", "left"], W: ["p", "_tr", "width"], H: ["p", "_tr", "height"], In: ["p", "_tp", "innerHTML"] }, { sample: "sample", init: true }, mix = function(id) { return document.getElementById(id); });
Теперь мою «крышу» уже ничего не спасет.
А ведь вместо вышестоящей банальщины могли быть чьи-нибудь полиморфные классы,
нейронно-сетевые скрипты и… СППР, зачатки ИИ. Ага. ;)
Вот еще, немного кода, ну, вдруг кто-то типа недавнешнего меня этого не знал:
var multiply1 = new Function("x", (function() { return "return x"; })()); alert(multiply1); var multiply2 = eval("new Function(\"x\", \(function(){ return \"return x\"; })()\)"); alert(multiply2); var multiply3 = new Function(["x", "y"], (function() { return "return x*y"; })()); alert(multiply3(5, 6)); var multiply4 = new Function(["x", ["y", "z"]], "return (x*y-z); "); alert(multiply4(5, 6, 10));
И, наконец, плюшка, «взорвавшая» мозг: теперь я понимаю, почему у function
typeof() конструктора тоже function!
Теперь мне также ясно — «почему до сих пор нет телепортеров».
Сумбурно получилось, но, может кому-то будет полезно почитать.
