programing

캡슐화된 익명 함수 구문 설명

copyandpastes 2022. 10. 19. 22:03
반응형

캡슐화된 익명 함수 구문 설명

요약

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);
}();

내게 그것을 설명할 수 있나요?

로 해석되고 있기 때문에 기능하지 않으며 함수 선언의 이름 ID는 필수입니다.

괄호로 둘러싸면 로 평가되며 함수식의 이름을 지정할 수 있습니다.

FunctionDeclaration음음음같 뭇매하다

function Identifier ( FormalParameterListopt ) { FunctionBody }

★★★★★★★★★★★★★★★★★.FunctionExpressions:

function Identifieropt ( FormalParameterListopt ) { FunctionBody }

Identifier(Identifieropt) 토큰 입력FunctionExpression에 함수식을 할 수 정의하지 않아도 .따라서 이름이 정의되지 않은 함수식을 가질 수 있습니다.

(function () {
    alert(2 + 2);
}());

또는 명명된 함수 식:

(function foo() {
    alert(2 + 2);
}());

괄호(공식적으로 그룹화 연산자라고 함)는 식만 둘러쌀 수 있으며 함수 식이 평가됩니다.

두 문법 제작은 모호할 수 있으며, 예를 들어 다음과 같이 완전히 동일하게 보일 수 있습니다.

function foo () {} // FunctionDeclaration

0,function foo () {} // FunctionExpression

를 알 수.FunctionDeclaration ★★★FunctionExpression표시되는 콘텍스트에 따라 다릅니다.

의 예에서는 쉼표 연산자도 식만을 처리할 수 있기 때문에 두 번째 예에서는 식입니다.

반,는FunctionDeclaration 's'라고 수 있어요.Program내의 외부 및 FunctionBody른른른른른

블록 내부의 기능은 예측할 수 없는 동작을 초래할 수 있으므로 피해야 합니다.

if (true) {
  function foo() {
    alert('true');
  }
} else {
  function foo() {
    alert('false!');
  }
}

foo(); // true? false? why?

'''가 됩니다.SyntaxError에는 스테이트먼트만 포함할 수 있지만(ECMAScript 사양에서는 함수 스테이트먼트를 정의하지 않습니다), 대부분의 구현에서는 허용성이 있으며 경고하는 두 번째 함수를 사용할 뿐입니다.'false!'.

Mozilla 실장(Rhino, SpiderMonkey)의 동작은 다릅니다.이들의 문법은 비표준 함수문을 포함하고 있습니다.즉, 함수는 해석 시간이 아닌 런타임에 평가됩니다.FunctionDeclaration에서는 첫 됩니다. 이러한 구현에서는 첫 번째 기능이 정의됩니다.


함수는 다양한 방법으로 선언할 수 있습니다.다음과 비교합니다.

1- 변수 곱셈에 할당된 함수 생성자로 정의된 함수:

var multiply = new Function("x", "y", "return x * y;");

2- 곱셈이라는 이름의 함수의 함수 선언:

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;
};

이것은 오래된 질문이지만, 지금까지 많은 개발자들이 혼란스러워하고 있는 토픽에 대해 설명하고 있습니다.내가 인터뷰한 JavaScript 개발자 후보 중 함수 선언과 함수식의 차이를 알려주지 못하고 즉시 호출되는 함수식이 무엇인지 전혀 알지 못한 사람은 셀 수 없다.

하지만 한 가지 매우 중요한 것은 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
};

물론 이름 ID를 함수 정의와 함께 사용하면 코드를 디버깅할 때 항상 도움이 되지만, 그것은 완전히 다른 것입니다. :-)

이미 좋은 답변들이 올라오고 있어요.그러나 함수 선언은 빈 완료 레코드를 반환합니다.

14.1.20 - 런타임 시멘틱스:평가하기

기능 선언:function Binding Identifier(바인딩 식별자) ( 형식 파라미터 ) { 기능 본체 }

  1. Normal Completion(비어 있음)을 반환합니다.

반환된 값을 가져오려는 대부분의 방법은 함수 선언을 함수식으로 변환하기 때문에 이 사실은 관찰하기가 쉽지 않습니다.하지만,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(){})().

javascript 에서는, 이것을 Immediate-Invoked Function Expression(IIFE)이라고 부릅니다.

함수를 함수식으로 만들려면 다음 작업을 수행해야 합니다.

  1. ()로 둘러싸다

  2. 그 앞에 무효 연산자를 두다.

  3. 변수에 할당합니다.

그렇지 않으면 함수 정의로 처리되어 다음 방법으로 동시에 호출/호출할 수 없습니다.

 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);
}();

위 구문은 유효하지 않습니다.java 스크립트 구문 파서는 function 키워드 뒤에 함수 이름을 찾기 때문에 오류를 발생시킵니다.

아마도 더 짧은 대답은 다음과 같을 것이다.

function() { alert( 2 + 2 ); }

는 (표준) 함수를 정의하는 함수 리터럴입니다.표현식으로 해석되는 추가 ()-쌍은 최상위 수준에서는 기대되지 않으며 리터럴만 기대됩니다.

(function() { alert( 2 + 2 ); })();

는 어나니머스 함수를 호출하는 표현문에 있습니다.

다음과 같은 매개 변수와 함께 사용할 수 있습니다.

var x = 3; 
var y = 4;

(function(a,b){alert(a + b)})(x,y)

결과적으로 7이 됩니다.

이러한 추가 괄호는 글로벌 네임스페이스와 코드를 포함하는 익명 함수 사이에 추가 익명 함수를 생성합니다.또한 Javascript에서 다른 함수에 선언된 함수는 해당 함수가 포함된 상위 함수의 네임스페이스에만 액세스할 수 있습니다.글로벌 스코프와 실제 코드 스코핑 사이에는 추가 객체(익명의 함수)가 존재하기 때문에 유지되지 않습니다.

다음과 같이 사용할 수도 있습니다.

! function() { console.log('yeah') }()

또는

!! function() { console.log('yeah') }()

!식으로 하므로 - negation op fn fn fn fn 을 사용하여 할 수 .()·사용과 동일0,fn def ★★★★★★★★★★★★★★★★★」void fn def

언급URL : https://stackoverflow.com/questions/1634268/explain-the-encapsulated-anonymous-function-syntax

반응형