Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   каменное объявление функции (https://javascript.ru/forum/misc/18145-kamennoe-obyavlenie-funkcii.html)

melky 19.06.2011 12:23

каменное объявление функции
 
вопрос вот в чем. есть функция, скажем, в которой есть ветвление, которое трудно высчитывается, но делается один раз.

так вот, есть два выхода (три даже), но не знаю,что выбрать... чистоту кода, скорость, или компактность?

разницы в скорости,как объявлять функцию, нет!
function abc(){

      if( fuckin_counting ){

          fucker_counter.*!*make*/!*Count( );

     } else {

          fucker_counter.*!*do*/!*Count( );

    }

}


да,да. видите названия методов? различие в первой половине. И еще, доступа к этим функциям я не имею (ну, браузеровские)

можно еще так

abc =  fuckin_counting ?

                      function(){

                           fucker_counter.makeCount();

                      }       :

                      function(){

                           fucker_counter.doCount();

                      }

да, я знаю, что возможно было и опустить анонимные обёртки. я пишу то, что у меня в редакторе, изменяя названия.

так вот, и еще третий способ. его я боюсь пробовать, потому что наслышан о производительности такого способа объявления.

abc = new Function ( "fucker_counter."+(fuckin_counting?"make":"do")+"Count()" )


но это фигня, потому что не видно локальных переменных.
тогда что, заюзать eval ?

eval( "abc = fucker_counter."+(fuckin_counting?"make":"do")+"Count()" )


кода там чуть больше, чем тут. там есть один аргумент у makeCount (или doCount), который пздц как написан в одну строчку. (свёрнут,короче говоря).

так что думаете ? не знаю, что выбрать.

щас посравниваю скорости


о yeah. я люблю этот сайт ))

вот тест как раз для меня

результаты вхроме примерно одинаковые (меньше 1% разница)

и в ФФ то же самое.

так что, для будущих поколений,

разницы в скорости,как объявлять функцию, нет!

SlavaPav 19.06.2011 13:03

Первый вариант функции самый наглядный, плюс определение функции поднимается. Eval - зло, это все знают. Лучше создать одну "ленивую" функцию для таких целей:
function someFunc(choice) {
    if (choice) {
        //something something
    } else {
        // something something
    }
    
    someFunc = function() {
        // новое тело фунции
    };
}


Недостаток: свойства и методы созданные до первого вызова функции не сохранятся.

Aetae 19.06.2011 13:04

abc=fucker_counter[fuckin_counting?'makeCount':'doCount'];

melky 19.06.2011 13:07

Цитата:

Сообщение от Aetae (Сообщение 109447)
function abc(){
  fucker_counter[fuckin_counting?'makeCount':'doCount']( );
}

чёрт,я совершенно забыл про это.)

я упомянул, что это функция не моя, а браузера. не увидел,наверное.

будет Illegal Invocation.. странно,но нету.

но тут еще и сохраняется буль в коде ф-и., если через console.dir смотреть



Цитата:

Сообщение от SlavaPav (Сообщение 109446)
Первый вариант функции самый наглядный, плюс определение функции поднимается. Eval - зло, это все знают. Лучше создать одну "ленивую" функцию для таких целей:
function someFunc(choice) {
    if (choice) {
        //something something
    } else {
        // something something
    }
    
    someFunc = function() {
        // новое тело фунции
    };
}


Недостаток: свойства и методы созданные до первого вызова функции не сохранятся.

хм,немного туманно. можно на частном случае, пожалуйста? для меня это что-то новое

SlavaPav 19.06.2011 13:28

"Ленивая" функция используется для задержки определения функции до ее первого вызова, если с функцией связан процесс инициализации который выолняется только один раз. Ну например если тебе нужно определить какие браузер поддерживает возможности и связать с этим функцию. Нет нужды каждый раз исполнять код определения возможностей, ведь браузер пользователя не поменяется магическим образом:
function some_func() {
    var result = (feature_detect) ? true : false;
    
    some_func = function() {
        if (result) {
            
        }
    };
    
    some_func();
}

melky 19.06.2011 13:51

не пойму. это ведь так происходит ? :
  1. первое исполнение, появляется область видимости
  2. переменная кеширует что-то то,что сложно считать. т.е. считает 1 раз.
  3. функция заменяет сама себя?
  4. исполняет саму себя ( но не саму себя, а ту, на что заменила сверху)
  5. область видимости сохраняется, переменная больше ничего не высчитывает

это как??? я про последнее.

функция ведь заменила саму себя, где нет этой переменной!
я не могу это быстро понять, как и замыкания :) в гугле кстати не нашел про это. не посоветуете ничего?

SlavaPav 19.06.2011 14:06

Можешь поискать "Отложенное определение функции" или "Самоопределяемая функция".
Флэнагана читал? Мне хватило его объяснений не тему замыканий. Могу попытаться объяснить.
function some_func() {
    var result = (feature_detect) ? true : false;
    
    /*
     * Так как область видимости у функций в javascript лексическая,
     *  то данная анонимная функция сохраняет 
     * цепочку областей видимости в которой она определена. 
     * То есть при вызове кода данной функции, неважно как она сохранена и
     * под каким именем, она будет иметь доступ к переменным из объемлющей функции. 
     * Вот и замыкание. Имя функции значения не
     * имеет, важно то, что во внешний код передается ссылка на вложенную анонимную функцию, 
     * и т. к. функция определена внутри
     * другой функции, она будет иметь доступ ко всем переменным объемлющей функции.
     */
    some_func = function() {
        if (result) {
            
        }
    };
    
    some_func();
}

melky 19.06.2011 14:25

хм, конечно читал. на хабре было попроще написано про это (по крайней мере,для меня)

просто, кажется, что, когда функция заменяется чем-либо, то область видимости пропадает. это логика так говорит :)

но в замыкании анонимная функция может отработать своё и испариться, а область видимости останется, конечно же.

значит,можно делать и так,если я усвоил ....

function a( ){ 

             var num='closure in func1'; 
             alert('fresh func 1');

             func=function(){   
                                   alert("num="+num+"\n\n function a : \n\n"+a)
                                   }
}

a(); // первый вызов

/* изменяем, но так, чтобы исполнение 
    было последовательным.

     я про то, что тут было бы,
     если бы написал внизу

     function a(){alert('another func')}
  */
a=function (){  alert('another func') }

a();
func();


у меня просто нет слов!

функция исполняется, делает свои дела, потом оставляет в window "телефон", на который можно позвонить (это func, там находится замыкание потом).

потом функция a заменяется чем-то другим, что делает совершенно другое
и имеет исходный код без всяких присваиваний!
красота!

это магия!!




..
не могу уже тебе плюсовать :)

SlavaPav 19.06.2011 14:35

Да, Javascript - чистая магия. :)

monolithed 19.06.2011 14:41

Цитата:

Сообщение от melky
у меня просто нет слов!

от чего столько восторга?
function foo() {
    var bar = function() {
         alert(true);
    };
}

foo();
bar(); //?

function foo() {
    return function() {
         alert(true);
    };
}

foo()();


Часовой пояс GMT +3, время: 02:19.