클로저에 대한 게시물을 읽고 있었으며 어디에서나 이것을 보았지만 어떻게 작동하는지에 대한 명확한 설명은 없습니다.
// 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/
이 게시물에서 이런 종류의 패턴에 대해 논의했습니다.
편집하다:
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 스크립트 사양에서 :
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)();
.