2017-01-23 5 views
3

Может кто-нибудь объяснить мне следующую функцию внутри JS файлJavascript Функция Определение Объяснение

function Init() 
{ 
    (function set() 
    { 
     -----code--- 
     print "hello"; 
     } 
    )(); 
} 

Если я вызываю функцию Init, она автоматически запускает функцию установки, а также или мне нужно вызвать набор() для запустить его?

+0

Да, потому что его IIFE определяет область вокруг вашего кода. В вашем случае это не имеет значения, потому что Init уже создал область. – Blauharley

ответ

0

Когда вы

(function set() { /*code here*/ })(); 

, это близкий эквивалент

var set = function() { /*code here*/ }; 
set(); 

Поэтому, когда вы вызываете Init(), вызывается функция set.

+0

Я бы сказал, что это не технически одинаково. В первом примере после вызова нет объектов, оставшихся в текущей области. Во втором примере у вас есть переменная 'set' в приведенном выше коде и ниже вызова (и она даже не указана ниже). – Zlatko

+0

@Zlatko 'В первом примере нет объектов, оставшихся в текущей области. Это ложь.В первом примере вы можете вызвать set() в любом месте функции Init, и он будет работать, в отличие от второго, где вы можете только вызвать set() после назначения. Даже в случае анонимной функции для него было создано внутреннее имя в среде области Init, и до того, как он даже начал интерпретировать первую строку функции Init. –

+0

nope, 'set' не доступен во внешней области или где-либо вне' set'. Проверьте это: https://gist.github.com/zladuric/dae9dc89297921f4f4023dee53e667fd Или я понял вас бессознательно? – Zlatko

0

Чтобы выполнить функцию, вам необходимо позвонить Init();.

(function() {console.log('IIFE') }());

Синтаксис вы имеете в виду это immediately-invoked function expression.

+0

есть опечатка еще – Blauharley

0

Это основное замыкание функции в js (внутренняя функция внутри другого).

также .. это анонимная функция ..meaning ... вы можете использовать эту функцию только один раз (и поэтому вызов функции привязан к торможению функции). так что ... подробнее об этой теме

function regular() 
{ 
    function regular_closure() 
    { 

    } 

    (function() // this is anonymous 
    { 

    })(); // call the anonymous function.. which is also a closure 

    regular_closure(); // call the function 
} 

:

MDN - js closures in depth

When to use js closure

+0

Я думаю, что это закрытие вводит в заблуждение. Каждая функция имеет замыкание переменных во внешних контекстах выполнения, а не только сразу вызываемых функций. Функция выполняется каждый раз, когда вызывается * regular *, поэтому на самом деле не используется только один раз, и это выражение функции, а не объявление. – RobG

+0

Да, это закрытие, но я думаю, что вопрос не затрагивает закрытие как таковое. С закрытием ничего не происходит, поэтому это не так важно. – Zlatko

+0

, что на самом деле, почему я прикрепил ссылку от MDN :) – ymz

1

Чтобы запустить любой код внутри него, необходимо позвонить Init. Теперь этот код внутри - это обычный код JavaScript, но интересный. Давайте посмотрим, почему.


Как

Ваша внутренняя функция является так называемая IIFE. Что вы можете сделать, чтобы упростить чтение внешней функции (Init), является замена внутренней функции результатом вызова IIFE.

Вот несколько примеров:

var x = undefined; // x === undefined 
x = (undefined); // again 
x = 3;  // x === 3 
x = (3); // again the same 
x = 'some string'; // some string 
x = ('some string'); // the same 

Так это нормально, чтобы положить () вокруг объекта, вы получите тот же объект. То же самое для функции

x = function() {}; // x is that function now. 
x = (function() {}); // the same. 

Но если вы говорите x = 3;, вы можете позвонить х?

x = 3; 
x(); // syntax error 
x = (3); 
x(); // again error. can't call a number. 

Но, если х является функцией, вы можете назвать это:

x = function() { console.log('Hi'); }; // you can call x now. 
x(); // logs 'Hi'! 

Так что, если вы делаете то же самое с скобкой, это то же самое:

x = (function() { console.log('Hi'); }); // again, the same. 
x(); // no error, function called again! 

Так вы может пропустить часть задания:

// instead of x = (...); and the x(), you replace the x part right away. 

(function() { console.log('Hi'); })() 
// function body  up to here ^^ now the call part. 

Обратите внимание, что он не будет работать без первой пары скобок:

function() { console.log('Hi'); }(); // syntax error. 

Так вы кладете внешние скобки () только актерский выражение функции в объект на месте.


Почему

Так вот, как это работает. Но почему? Потому что вы хотите удостовериться, что никто не называет вашу функцию! Если вы сделаете это:

var x = function() {}; 
x(); 

В настоящее время существуют по крайней мере две вещи, которые могут случиться, что вы не можете:

  1. Там может быть имя столкновение. Возможно, вы не знаете, существует ли уже «х», где бы внешняя функция вызывалась, например, вы bind Инициируйте какой-либо объект, который имеет x в области или что-то в этом роде.

  2. Кто-то может «украсть» ваш х и называть его снова. Не обязательно воровать, вы просто просачиваетесь (тонкая ошибка) и некоторые другие кодовые вызовы x, ожидая найти свой собственный x, но на самом деле это ваш x сейчас, потому что он доступен. И ты хотел, чтобы этого не было.

Таким образом, вы легко блокируете его в анонимной функции, которая была выполнена сразу.

Надеюсь, это немного облегчит ситуацию.

+0

»* Таким образом, вы помещаете внешние parens() просто чтобы включить эту функцию в объект на месте. * ". Фактически внешняя скобка изменяет то, что может быть объявлением функции в выражении функции. Любой акцептор может использоваться, который разрешен в начале инструкции, например. '+', '-' или'! 'как в'! function() {}() '. ;-) – RobG

+0

@RobG Удивительный! TIL! Function() {console.log ('a'); }() https://twitter.com/zladuric/status/823632051572248577 – Zlatko

+0

Yep, сохраняет один символ (функция() {}()). ;-) – RobG