Pull to refresh

Javascript — персональное безумие

Reading time 3 min
Views 1.7K

Есть случайное такое хобби — программирование на 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];
    }
})()

и, может быть в этой конструкции даже есть не совсем очевидный какой-нибудь смысл…


Пусть, допустим, есть:

  1. Функция, которая что-то делает.
    например так:

    var mix = function (id){ return document.getElementById(id); }

    :) — типа она сильно упрощает жизнь.


    и к ней, приложено, например:
    mix.s = function (id){ mix(id).style; };


    Сразу скажу, чтобы потом не было вопросов:
    я знаю про JQuery, Prototype, Script.Aculo.us и т.п.
    Я понимаю, что это гораздо удобней чем писать своё.
    Смысл статьи не в том, чтобы писать framework.



  2. Решили немножко улучшить функционал, вот так:

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

    Банально, не правда ли?
    Это всё для примера, так что не ругайтесь.

  3. Теперь вернемся немного назад, к безымянным функциям (замыканиям).

    (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!



Теперь мне также ясно — «почему до сих пор нет телепортеров».



Сумбурно получилось, но, может кому-то будет полезно почитать.





Tags:
Hubs:
+39
Comments 64
Comments Comments 64

Articles