Есть случайное такое хобби — программирование на 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!
Теперь мне также ясно — «почему до сих пор нет телепортеров».
Сумбурно получилось, но, может кому-то будет полезно почитать.