요약
JavaScript로 캡슐화 된 익명 함수에 대한 구문의 이유를 설명 할 수 있습니까? 왜 이것이 효과 (function(){})();
가 function(){}();
있습니까?
내가 아는데 것을
JavaScript에서 다음과 같은 명명 된 함수를 만듭니다.
function twoPlusTwo(){
alert(2 + 2);
}
twoPlusTwo();
익명 함수를 만들어 변수에 할당 할 수도 있습니다.
var twoPlusTwo = function(){
alert(2 + 2);
};
twoPlusTwo();
익명 함수를 만든 다음 대괄호로 묶고 즉시 실행하여 코드 블록을 캡슐화 할 수 있습니다.
(function(){
alert(2 + 2);
})();
이것은 Greasemonkey 스크립트, jQuery 플러그인 등과 같이 잠재적으로 충돌하는 변수로 현재 범위 또는 전역 범위를 어지럽히 지 않도록 모듈 식 스크립트를 만들 때 유용합니다.
이제 이것이 왜 작동하는지 이해합니다. 괄호는와 같이 내용을 묶고 결과 만 표시합니다 (나는 그것을 설명하는 더 좋은 방법이 있다고 확신합니다) (2 + 2) === 4
.
내가 이해하지 못하는 것
그러나 이것이 왜 똑같이 작동하지 않는지 이해하지 못합니다.
function(){
alert(2 + 2);
}();
저에게 설명해 주시겠습니까?
답변
로 구문 분석되고 있기 때문에 작동하지 않으며 FunctionDeclaration
함수 선언의 이름 식별자는 필수 입니다.
괄호로 묶으면로 평가되며 FunctionExpression
함수 표현식의 이름을 지정할 수 있습니다.
문법은 FunctionDeclaration
다음과 같습니다.
function Identifier ( FormalParameterListopt ) { FunctionBody }
그리고 FunctionExpression
s :
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
보시다시피 Identifier
(Identifier opt ) 토큰 FunctionExpression
은 선택 사항이므로 이름을 정의하지 않고 함수 표현식을 가질 수 있습니다.
(function () {
alert(2 + 2);
}());
또는 명명 된 함수 표현식 :
(function foo() {
alert(2 + 2);
}());
괄호 (공식적으로 그룹화 연산자 라고 함 )는 표현식 만 둘러 쌀 수 있으며 함수 표현식이 평가됩니다.
두 개의 문법 제작은 모호 할 수 있으며 다음과 같이 정확하게 똑같이 보일 수 있습니다.
function foo () {} // FunctionDeclaration
0,function foo () {} // FunctionExpression
구문 분석기는 표시 되는 컨텍스트 에 따라 a FunctionDeclaration
또는 a 인지 알고 있습니다.FunctionExpression
위의 예에서 쉼표 연산자 는 표현식 만 처리 할 수 있으므로 두 번째 표현식은 표현식입니다.
반면에, FunctionDeclaration
s는 실제로 ” Program
“코드, 즉 전역 범위 외부 및 FunctionBody
다른 함수 내부의 코드를 의미하는 코드 에만 나타날 수 있습니다.
블록 내부의 함수는 다음과 같은 예기치 않은 동작을 유발할 수 있으므로 피해야합니다.
if (true) {
function foo() {
alert('true');
}
} else {
function foo() {
alert('false!');
}
}
foo(); // true? false? why?
위의 코드는 실제로 명령문을 포함 할 수 SyntaxError
있기 때문에 실제로는을 생성해야 Block
하지만 ECMAScript 사양은 함수 명령문을 정의하지 않습니다. 그러나 대부분의 구현은 허용되며 두 번째 함수 인 간단하게 경고합니다 'false!'
.
Mozilla 구현 (Rhino, SpiderMonkey)은 다른 동작을합니다. 이들의 문법에는 비표준 함수 명령문이 포함되어 있습니다. 이는 함수가 s에서 발생하는 구문 분석 시간이 아니라 런타임에 평가됨을 의미합니다 FunctionDeclaration
. 이러한 구현에서 첫 번째 함수가 정의됩니다.
함수는 다른 방식으로 선언 될 수 있으며 다음을 비교하십시오 .
1- 변수에 곱한 함수 생성자로 정의 된 함수 곱하기 :
var multiply = new Function("x", "y", "return x * y;");
2- multiply 라는 함수의 함수 선언 :
function multiply(x, y) {
return x * y;
}
3- 변수에 곱한 함수 표현식 :
var multiply = function (x, y) {
return x * y;
};
4- 변수에 곱하는 명명 된 함수 표현식 func_name :
var multiply = function func_name(x, y) {
return x * y;
};
답변
이것은 오래된 질문과 답변이지만 오늘날 많은 개발자들이 루프를 던지는 주제에 대해 설명합니다. 나는 나에게 함수 선언과 함수 표현식의 차이 말할 수있는 자바 스크립트 개발자 후보 내가 인터뷰 한의 수를 셀 수 없다 하고 있는 즉시 호출 함수 표현식이 무엇인지 단서가 없었다 있습니다.
그래도 Premasagar의 코드 스 니펫에 이름 식별자를 부여해도 작동하지 않는다는 매우 중요한 점을 언급하고 싶습니다.
function someName() {
alert(2 + 2);
}();
이것이 작동하지 않는 이유는 JavaScript 엔진이 이것을 함수 선언으로 해석하고 표현식이 포함되지 않은 완전히 관련되지 않은 그룹화 연산자를 해석하고 그룹화 연산자 는 표현식을 포함 해야 하기 때문입니다. JavaScript에 따르면 위의 코드 조각은 다음 코드 조각과 같습니다.
function someName() {
alert(2 + 2);
}
();
일부 사람들에게 유용 할 수있는 또 다른 점은 함수 정의 자체를 제외하고 코드의 맥락에서 함수 표현식에 제공하는 이름 식별자가 거의 쓸모가 없다는 것입니다.
var a = function b() {
// do something
};
a(); // works
b(); // doesn't work
var c = function d() {
window.setTimeout(d, 1000); // works
};
물론 함수 정의와 함께 이름 식별자를 사용하면 코드 디버깅과 관련하여 항상 도움이되지만 완전히 다른 것입니다 : 🙂
답변
큰 답변이 이미 게시되었습니다. 그러나 함수 선언은 빈 완료 레코드를 반환합니다.
FunctionDeclaration :
function
BindingIdentifier 형식(
매개 변수)
{
FunctionBody}
- 정상 완료 (비어 있음)를 반환합니다 .
반환 된 값을 얻는 대부분의 방법은 함수 선언을 함수 표현식으로 변환하기 때문에이 사실은 관찰하기 쉽지 않습니다. 그러나 eval
그것을 보여줍니다 :
var r = eval("function f(){}");
console.log(r); // undefined
빈 완료 레코드를 호출하는 것은 의미가 없습니다. 그것이 function f(){}()
작동하지 않는 이유 입니다. 실제로 JS 엔진은이를 호출하려고 시도하지 않으며 괄호는 다른 문의 일부로 간주됩니다.
그러나 함수를 괄호로 묶으면 함수 표현식이됩니다.
var r = eval("(function f(){})");
console.log(r); // function f(){}
함수 표현식은 함수 객체를 반환합니다. 따라서 다음과 같이 호출 할 수 있습니다 (function f(){})()
..
답변
자바 스크립트에서는이를 즉시 호출 된 함수 표현식 (IIFE)이라고 합니다.
함수 표현식으로 만들려면 다음을 수행하십시오.
-
()를 사용하여 묶습니다.
-
무효 연산자를 배치하기
-
변수에 할당하십시오.
그렇지 않으면 함수 정의로 취급되며 다음과 같은 방법으로 함수를 동시에 호출 / 호출 할 수 없습니다.
function (arg1) { console.log(arg1) }();
위의 오류가 발생합니다. 함수 표현식 만 즉시 호출 할 수 있기 때문입니다.
몇 가지 방법으로 달성 할 수 있습니다. 방법 1 :
(function(arg1, arg2){
//some code
})(var1, var2);
방법 2 :
(function(arg1, arg2){
//some code
}(var1, var2));
방법 3 :
void function(arg1, arg2){
//some code
}(var1, var2);
방법 4 :
var ll = function (arg1, arg2) {
console.log(arg1, arg2);
}(var1, var2);
위의 모든 것은 즉시 함수 표현식을 호출합니다.
답변
또 다른 작은 말이 있습니다. 코드는 약간만 변경하면 작동합니다.
var x = function(){
alert(2 + 2);
}();
더 널리 퍼진 버전 대신 위의 구문을 사용합니다.
var module = (function(){
alert(2 + 2);
})();
vim에서 javascript 파일에 대해 들여 쓰기가 올바르게 작동하지 않았기 때문입니다. vim은 열린 괄호 안의 중괄호를 좋아하지 않는 것 같습니다.
답변
아마도 더 짧은 대답은
function() { alert( 2 + 2 ); }
(익명) 함수 를 정의 하는 함수 리터럴 입니다 . 표현식으로 해석되는 추가 () 쌍은 최상위 수준이 아니라 리터럴 만 예상됩니다.
(function() { alert( 2 + 2 ); })();
에 표현 문익명 함수 를 호출 에 있습니다.
답변
(function(){
alert(2 + 2);
})();
괄호 안에 전달 된 것은 함수 표현식으로 간주되므로 위의 유효한 구문입니다.
function(){
alert(2 + 2);
}();
위의 구문은 유효하지 않습니다. Java 스크립트 구문 분석기는 오류를 발생시키는 항목을 찾지 못하므로 함수 키워드 다음에 함수 이름을 찾습니다.