Шұғыл функциялар қандай?

Мен біраз уақыттан бері JS-де бағдарламалаудамын, бірақ мен жедел қызметті пайдаланудың қажеті жоқ, мысалы:

(function(){
    console.log('hello, I am an immediate function');
}())

Егер мен жай ғана жазған болсам, немен ерекшеленеді:

console.log('hello, I am an immediate function');

? Менде бұл функцияға кез-келген рұқсат жоқ (ол еш жерде тағайындалмайды). Менің ойымша (бірақ мен сенімді емес) барлық функцияларды дереу іске асыра алмаймын деп ойлаймын, сондықтан адамдар оны не үшін пайдаланады?

0
Сіздің жағдайыңызда шын мәнінде ешқандай айырмашылық жоқ (қоңырау стакасы мен баяу орындау). Бірақ жоқ, бәрін де онсыз жасай алмайды.
қосылды автор Bergi, көзі
google «Javascript Self Invoking Functions», сізде бірнеше нәрсені оқуға болады, және бәрі кейін анықталуы керек ...
қосылды автор AntouanK, көзі

6 жауаптар

Update:
I've found this question where I did go into more details on closures, comlete with little drawings to clarify how closures, and function scopes are used (and how they can help you).

IIFE's, being function objects, are the only way to create real scopes in JS. They're used all over the place. Have you ever used jQuery, or some other lib? then you've used code that uses IIFE's.
Ever looked into node.js? Then you might have come across something called "the module pattern".
If you've had a go at writing your own constructor, you've probably wondered how you could have some sort of private property onto an object. The answer is IIFE's time and time again.

Сонымен қатар: DOM api - әлемдегі ең жылдам нәрсе емес. Қатты кодталған document.getElementById функциясы бар функция бар болса, бұл функция әр шақырылған кезде DOM өтіп кетеді. Бұл мінсіз емес. Бұл мәселені шешудің жылдам әрі оңай жолы мыналар еді:

var f = (function(domReference)
{
    var visible = !!(domReference.style.visibility === 'block')
    return function()
    {//has access to vars and arguments of outer function
        domReference.style.visibility = visible ? 'none' : 'block';
        visible = !visible;
    }
}(document.getElementById('foobar'));

Бірақ ең жақсы және ең кең тараған мысал - циклдардағы үзілістер/интервалдар:

for (var i=0;i<10;i++)
{
    setTimeout((function(currentI)
    {
        return function()
        {
            console.log(currentI);
            console.log(i);
        }
    }(i)), 1000);

Мұнда currentI 0, 1, 2 ... және т.б. кіреді, ал i әрқашан әрқашан 10 . Таймаутқа кері шақырудың себебі i мәнінің көшірмесі болмайды, бірақ сілтемелер айнымалы i . Бұл айнымалы мән оның қалауы бойынша қаншалықты өзгерте алатынын, күту уақыты кері шақырылған кезде, i мәнін соңғы тағайындалған кез келген мәнге енгізу керек болады. Кері байланыс анықталған кезде i мәні тағайындалмады.

Тым көп егжей-тегжейге кірмей, мен объектілерге арналған жеке меншік объектілер туралы айттым Міне, IIFE және функционалдық мүмкіндіктерінің неге шешуші маңызы бар екенін және JS-тің керемет күшті иегері:

var MyConstructor = (function()
{
    return function(foo, bar)
    {
        var initState = Array.prototype.slice.apply(arguments, [0]);
        this.getInit = function()
        {
            return initState;
        };
        this.foo = foo;
        this.bar = bar;
    }
}());
(function(constant)
{
    var F = function(args)
    {
        return MyConstructor.apply(this, args);
    },
    checkVar = constant || 'default constant value';
    F.prototype = MyConstructor.prototype;
    MyConstructor.prototype.getConstant = function()
    {
        if (constant !== checkVar)
        {//bad example
            return checkVar;
        }
        return constant;
    };
    MyConstructor.prototype.regularMethod = function()
    {
        return this.foo;
    };
    MyConstructor.prototype.copyFromInitState = function()
    {
        return new F(this.getInit());
    };
}('Immutable value'));

Бұл жұмысты қызықтыр ...: P

4
қосылды
шындық емес ауқымы қандай? Функция атаусыздығына сілтеме жасайсыз ба?
қосылды автор Bergi, көзі
Жақсы, бірақ сіз сондай-ақ «дереу» орындамаған, бірақ қандай да бір түрде сілтеме жасамайтын қалыпты функциялары бар «нақты» аумақтарды жасай аласыз.
қосылды автор Bergi, көзі
@Bergi: Жоқ, JS-ке сілтеме жасамаймын (әлі де) allow айнымалы немесе блоктық ауқымы бар. Кейбір адамдар объектінің литералдарын және delete уақытша мәндерін пайдаланады, ол «ауқымды нысан»
қосылды автор Elias Van Ootegem, көзі
@Bergi: Өңделген жауап, F IIFE бөлігінің ауқымды жасайтыны екенін көрсетті. :)
қосылды автор Elias Van Ootegem, көзі

Immediately invoked function expressions are used to create namespaces. I won't explain precisely why an IIFE is so important - Ben Alman does a mighty good job at that. Nevertheless, I will say that one of the most important uses of an IIFE is to create closures. Consider:

var counter = (function() {
    var count = 0;

    return function() {
        return ++count;
    };
}());

console.log(counter());//1
console.log(counter());//2
console.log(counter());//3

IIFE-ді пайдаланғанымыздың себебі - JavaScript блокты шектеуі жоқ. Осылайша IIFE блоктық ауқымды имитациялау үшін қолданылады. JavaScript 1.7 нұсқасын блок-ауқымды айнымалыларды жасауға мүмкіндік беретін let кілт сөзін ұсынды. Дегенмен, көптеген іске асырулар let қолдамайды, демек біз IIFE-ді қолданамыз.

Мысалы, жоғарыда көрсетілген бағдарламаны let кілт сөзін келесі түрде қолдану арқылы қайта жазуға болады:

var counter;

{
    let count = 0;

    counter = function() {
        ++count;
    };
}

console.log(counter());//1
console.log(counter());//2
console.log(counter());//3

Сондай-ақ, IIFE мәндерді қайтара алатынын ескеріңіз. Қалыпты блоктар мұны жасай алмайды. Демек, сіз айнымалы мәнді жаһандық айнымалыға қолмен тағайындауыңыз керек.

Негізінен IIFE кітапхананың жекеменшігін инкапсулау үшін пайдаланылады. Бұл жаһандық ауқымды жасаудың жаман тәжірибесі.

Кейде ол ұқсас элементтерді логикалық түрде инкапсуляциялау үшін пайдаланылады, өйткені біз адамдарға топтық заттарды ұнатамыз. Бұл шынымен де өзгермейді, бірақ кодексті ұйымдастыру жақсы. Мысалы, мынаны қарастырайық:

function Pet(name) {
    this.name = name;
}

Pet.prototype.feed = function (food) {
    console.log(this.name + " is eating " + food + ".");
};

Мұның орнына сіздің кодыңызды төмендегідей инкапсуляциялау жақсы көрінеді:

var Pet = (function() {
    function Pet(name) {
        this.name = name;
    }

    Pet.prototype.feed = function (food) {
        console.log(this.name + " is eating " + food + ".");
    };

    return Pet;
}());

Oh, most important. An IIFE is also used to solve the Javascript infamous Loop issue?

4
қосылды
Ал, теориялық аумақтар аттар кеңістігі ретінде қарастыруға болады , аттар кеңістігі термині әдетте JS жүйесінде модуль нысандарына (нүктелік белгілермен қатынасады) қатысты.
қосылды автор Bergi, көзі

let - бұл болашақ сақталған кілт сөзді және ES6 дейін қосылмайды. Chrome тек экспериментальды мүмкіндік ретінде оны қолдайды және оны Mozilla өз JS

қосылды автор Elias Van Ootegem, көзі

Әзірлеушілер дербес аумақтарды жариялау үшін дереу функцияларды пайдаланады. Мысалы...

(function($){
   $("div").html("example");
})(jQuery);

Бұл кодпен жаһандық ауқымда $ айнымалысы қажет емес, тек window.jQuery сыртында. Басқа кодтар терезесінде window нысанында қолданылатын айнымалы атауларды пайдаланғыңыз келгенде (мысалы, сіз терезесін қолданыңыз. ) Prototype.js).

1
қосылды

People use it because its one of the most powerful features in javascript. Have a read and welcome to Javascript. http://javascript.crockford.com/private.html

1
қосылды

Өзін-өзі шақыратын функциялар жаһандық ауыспалы соқтығысудың алдын алу үшін қолданылады. Мысалға:

(function($){
    //your code 
})(jQuery);

Жоғарыда келтірілген мысалда jQuery және Prototype.js файлын пайдаланатын бетте болсаңыз, сіз $ нысанына қауіпсіз сілтеме жасай аласыз және $ jQuery'ның прототиптің $ нысанына жатпайтын нысанын біле аласыз.

1
қосылды
Енді сіздің aliasing кодыңыз жаһандық айнымалы соқтығысудың алдын-алу мысалы емес ...
қосылды автор Bergi, көзі
IIFE-те bar = 'foo' жазатын болсам, мен әлі де жаһандық ауқымды (болжалды глобаллер)
қосылды автор Elias Van Ootegem, көзі

Адамдар оны жеке меншік кеңістіктің эмуляциясы деп түсіндіреді. Анонимді функцияның құрылымында анықталған кез-келген айнымалы терезе сыртқа қарай жасырылады (әдетте window және window ).

0
қосылды
Жеткілікті әділ, жойылды.
қосылды автор Tommi, көзі
(function() {} ()) қолдануға жарамды. Крокфорд бұл стильді жақсы көреді.
қосылды автор Mark Dee, көзі