[javascript] 같은 줄에서 익명 함수를 호출해야하는 이유는 무엇입니까?

클로저에 대한 게시물을 읽고 있었으며 어디에서나 이것을 보았지만 어떻게 작동하는지에 대한 명확한 설명은 없습니다.

// Create a new anonymous function, to use as a wrapper
(function(){
    // The variable that would, normally, be global
    var msg = "Thanks for visiting!";

    // Binding a new function to a global object
    window.onunload = function(){
        // Which uses the 'hidden' variable
        alert( msg );
    };
// Close off the anonymous function and execute it
})();

Ok 새로운 익명 함수를 만든 다음 실행할 것입니다. 그런 다음이 간단한 코드가 작동해야합니다 (그렇습니다).

(function (msg){alert(msg)})('SO');

내 질문은 여기서 어떤 종류의 마술이 일어나는가? 나는 내가 쓸 때 다음과 같이 생각했다.

(function (msg){alert(msg)})

그러면 함수 “”(msg) …와 같이 이름이 지정되지 않은 새로운 함수가 생성됩니다.

그런데 왜 이것이 작동하지 않습니까?

(function (msg){alert(msg)});
('SO');

왜 같은 줄에 있어야합니까?

게시물을 알려주거나 설명해 주시겠습니까?



답변

함수 정의 후에 세미콜론을 삭제하십시오.

(function (msg){alert(msg)})
('SO');

위의 작동해야합니다.

데모 페이지 : https://jsfiddle.net/e7ooeq6m/

이 게시물에서 이런 종류의 패턴에 대해 논의했습니다.

jQuery와 $ 질문

편집하다:

ECMA 스크립트 사양 을 보면 함수를 정의 할 수있는 3 가지 방법이 있습니다. (페이지 98, 섹션 13 기능 정의)

1. 함수 생성자 사용

var sum = new Function('a','b', 'return a + b;');
alert(sum(10, 20)); //alerts 30

2. 함수 선언 사용.

function sum(a, b)
{
    return a + b;
}

alert(sum(10, 10)); //Alerts 20;

3. 함수 표현

var sum = function(a, b) { return a + b; }

alert(sum(5, 5)); // alerts 10

따라서 선언과 표현의 차이점은 무엇입니까?

ECMA 스크립트 사양에서 :

a

FunctionDeclaration : 함수 식별자 (FormalParameterListopt) {FunctionBody}

FunctionExpression : 함수 식별자 (FormalParameterListopt) {FunctionBody}

함수 식별자에서 ‘식별자’는 선택 사항 입니다. 그리고 식별자를 제공하지 않으면 익명 함수를 만듭니다. 식별자를 지정할 수 없다는 의미는 아닙니다.

이것은 다음이 유효 함을 의미합니다.

var sum = function mySum(a, b) { return a + b; }

중요한 점은 mySum 함수 본문 내에서만 ‘mySum’을 사용할 수 있다는 것입니다. 다음 예를 참조하십시오.

var test1 = function test2() { alert(typeof test2); }

alert(typeof(test2)); //alerts 'undefined', surprise! 

test1(); //alerts 'function' because test2 is a function.

라이브 데모

이것을 다음과 비교하십시오

 function test1() { alert(typeof test1) };

 alert(typeof test1); //alerts 'function'

 test1(); //alerts 'function'

이 지식으로 무장 한 코드를 분석해 봅시다.

다음과 같은 코드가 있으면

    function(msg) { alert(msg); }

함수 표현식을 작성했습니다. 이 함수 표현식을 괄호로 묶어 실행할 수 있습니다.

    (function(msg) { alert(msg); })('SO'); //alerts SO.


답변

이를 자체 호출 함수라고합니다.

호출 할 때 (function(){})함수 객체를 반환합니다. 추가하면 ()호출되고 본문의 모든 것이 실행됩니다. 는 ;2 호출이 실패하는 이유 즉, 문장의 끝을 의미한다.


답변

내가 혼란스럽게 생각한 것은 “()”가 그룹화 연산자라는 것입니다.

기본적으로 선언 된 함수는 다음과 같습니다.

전의. 1:

var message = 'SO';

function foo(msg) {
    alert(msg);
}

foo(message);

함수는 객체이며 그룹화 할 수 있습니다. 함수 주위에 parens를 던져 보자.

전의. 2 :

var message = 'SO';

function foo(msg) {  //declares foo
    alert(msg);
}

(foo)(message);     // calls foo

이제 동일한 함수를 선언하고 즉시 호출하는 대신 기본 대체를 사용하여 호출 할 때 선언 할 수 있습니다.

전의. 삼.

var message = 'SO';

(function foo(msg) {
    alert(msg);
})(message);          // declares & calls foo

마지막으로 이름을 사용하지 않기 때문에 추가 foo가 필요하지 않습니다! 함수는 익명 일 수 있습니다.

전의. 4.

var message = 'SO';

(function (msg) {   // remove unnecessary reference to foo
    alert(msg);
})(message);

질문에 대답하려면 예 2를 다시 참조하십시오. 첫 번째 줄은 이름없는 함수를 선언하고 그룹화하지만 호출하지는 않습니다. 두 번째 줄은 문자열을 그룹화합니다. 둘 다 아무것도하지 않습니다. (Vincent의 첫 번째 예)

(function (msg){alert(msg)});
('SO');                       // nothing.

(foo);
(msg); //Still nothing.

그러나

(foo)
(msg); //works


답변

익명 함수는 이름이 “”인 함수가 아닙니다. 단순히 이름이없는 함수입니다.

JavaScript의 다른 값과 마찬가지로 함수는 이름을 만들 필요가 없습니다. 실제로 다른 값과 마찬가지로 이름에 바인딩하는 것이 훨씬 더 유용합니다.

그러나 다른 값과 마찬가지로 이름에 바인딩하지 않고 사용하려는 경우가 있습니다. 이것이 자기 호출 패턴입니다.

다음은 함수와 숫자이며 바인딩되지 않습니다. 아무 것도하지 않으며 절대 사용할 수 없습니다 :

function(){ alert("plop"); }
2;

따라서 다른 값과 마찬가지로 변수를 변수에 저장하여 사용할 수 있습니다.

var f = function(){ alert("plop"); }
var n = 2;

구문 설탕을 사용하여 함수를 변수에 바인딩 할 수도 있습니다.

function f(){ alert("plop"); }
var n = 2;

그러나 이름을 지정할 필요가없고 더 혼란스럽고 가독성이 떨어지면 바로 사용할 수 있습니다.

(function(){ alert("plop"); })(); // will display "plop"
alert(2 + 3); // will display 5

여기서 내 함수와 숫자는 변수에 바인딩되지 않지만 여전히 사용할 수 있습니다.

이와 같이, 자기 호출 기능에는 실제 가치가없는 것처럼 보입니다. 그러나 JavaScript 범위 구분 기호는 블록이 아니라 함수라는 것을 명심해야합니다 ({}).

따라서 자체 호출 함수는 실제로 C ++, C # 또는 Java 블록과 동일한 의미를 갖습니다. 이는 내부에서 생성 된 변수가 범위 외부에서 “누설”되지 않음을 의미합니다. 이것은 전역 범위를 오염시키지 않기 위해 JavaScript에서 매우 유용합니다.


답변

JavaScript가 작동하는 방식입니다. 명명 된 함수를 선언 할 수 있습니다.

function foo(msg){
   alert(msg);
}

그리고 그것을 부르십시오 :

foo("Hi!");

또는 익명 함수를 선언 할 수 있습니다.

var foo = function (msg) {
    alert(msg);
}

그리고 그것을 부르십시오 :

foo("Hi!");

또는 함수를 이름에 바인딩 할 수 없습니다.

(function(msg){
   alert(msg);
 })("Hi!");

함수는 함수를 반환 할 수도 있습니다.

function make_foo() {
    return function(msg){ alert(msg) };
}

(make_foo())("Hi!");

본문에 “var”로 정의 된 변수가 다음 make_foo에 의해 반환 된 각 함수에 의해 닫히는 것은 가치가 없습니다.make_foo . 이것은 폐쇄이며, 한 기능에 의해 변경된 값이 다른 기능에 의해 보일 수 있음을 의미합니다.

원하는 경우 정보를 캡슐화 할 수 있습니다.

function make_greeter(msg){
    return function() { alert(msg) };
}

var hello = make_greeter("Hello!");

hello();

거의 모든 프로그래밍 언어이지만 Java가 작동하는 방식입니다.


답변

당신이 보여주는 코드

(function (msg){alert(msg)});
('SO');

문장 으로 구성됩니다 . 첫 번째는 함수 객체를 생성하는 표현식입니다 (저장되지 않기 때문에 가비지 수집 됨). 두 번째는 문자열을 생성하는 표현식입니다. 함수를 문자열에 적용하려면, 문자열이 생성 될 때 (위에도 표시됨) 함수에 인수로 문자열을 전달하거나 실제로 함수를 변수에 저장해야합니다. 나중에 여가에 적용하십시오. 이렇게 :

var f = (function (msg){alert(msg)});
f('SO');

변수에 익명 함수 (람다 함수)를 저장하면 효과적으로 이름을 부여 할 수 있습니다. 따라서 일반 함수를 정의 할 수도 있습니다.

function f(msg) {alert(msg)};
f('SO');


답변

이전 의견을 요약하면 다음과 같습니다.

function() {
  alert("hello");
}();

변수에 지정되지 않으면 구문 오류가 발생합니다. 코드는 함수 구문 (또는 정의)으로 구문 분석되어 닫는 괄호가 구문 상 올바르지 않게됩니다. 함수 부분에 괄호를 추가하면 인터프리터 (및 프로그래머)에게 다음과 같이 함수 표현식 (또는 호출)임을 알 수 있습니다.

(function() {
  alert("hello");
})();

이것은 자체 호출 기능으로, 익명으로 작성되고 선언 된 동일한 행에서 호출이 발생하므로 즉시 실행됩니다. 이 자체 호출 함수는 인수없는 함수를 호출하는 친숙한 구문과 함수 이름 주위에 괄호를 추가하여 표시됩니다 (myFunction)();.

좋은의 SO 토론 자바 스크립트 함수 구문은 .