느낌표는 기능 전에 무엇을합니까?


1242
!function () {}();

4
@Dykam 그것의 유용성은이 답변에서 설명됩니다 : stackoverflow.com/questions/5422585/…
hectorct


1
우리는 그것을 호출하는 익명 함수를 자기가-실행 ---
befzz

7
@befzz이 기사에서 나중에 설명하는 것처럼 "즉시 호출 된 함수 표현식"이라고하는 것이 좋습니다 ( "자기 실행"은 재귀를 의미 함)
Zach Esposito

답변:


2117

JavaScript 구문 101. 다음은 함수 선언 .

function foo() {}

세미콜론은 없습니다 : 이것은 단지 함수 선언 입니다. foo()실제로 함수를 실행하려면 호출이 필요합니다 .

무해한 느낌표를 추가 !function foo() {}하면 표현 . 이제 함수 표현식 입니다.

!혼자는 물론, 함수 호출하지 않지만, 우리는 지금 넣을 수 있습니다() 말 : !function foo() {}()보다 더 높은 우선 순위를 가지고 있습니다 !및 즉시 함수를 호출합니다.

저자가하는 일은 함수 표현 식당 바이트를 저장하는 것입니다. 더 읽기 쉬운 방법은 다음과 같습니다.

(function(){})();

마지막으로 !표현식이 true를 반환합니다. 이는 기본적으로 모든 인생 리턴입니다 undefined우리 잎, !undefined이다 true. 특별히 유용하지 않습니다.


229
+1. 이것은 실제로 가장 좋은 대답이며 슬프게도 거의지지하지 않습니다. 분명히, !부울을 반환하지만, 우리 모두 알고 있지만, 중요한 점은 함수 선언문을 함수 표현식으로 변환하여 괄호로 묶지 않고 함수를 즉시 호출 할 수 있다는 것입니다. 명확하지 않으며 코더의 의도가 분명합니다.
gilly3

64
+1 이것은 실제로 왜 당신이 이것을하기를 원하는지에 대한 유일한 답이며, 왜 리턴 결과의 부정이 보증하는 것보다 더 많이 사용했는지 알 수 있습니다. 단항 연산자! (또한 ~,-및 +)는 함수 선언을 명확하게하고 끝에있는 parens가 함수를 제자리에서 호출 할 수 있도록합니다. 모듈 식 코드를 작성할 때 변수에 대한 로컬 범위 / 이름 공간을 만들기 위해 종종 수행됩니다.
Tom Auger

65
또 다른 장점은! 세미콜론 삽입을 유발하므로이 버전이;으로 끝나지 않는 파일과 잘못 연결되는 것은 불가능합니다. () 형식이 있으면 이전 파일에 정의 된대로 함수 호출로 간주됩니다. 동료에게주는 모자 끝.
Jure Triglav

5
@Carnix var foo =는 진술 / 표현 모호함을 깨뜨리고 간단히 쓸 수 있습니다 var foo = function(bar){}("baz");.
Neil

6
이것은 일반적으로 모든 단일 바이트가 계산되는 축소 / 증거 스크립트에 의해 수행됩니다.
Dima Slivin

367

함수:

function () {}

아무것도 (또는 정의되지 않은) 반환합니다.

때로는 함수를 만들 때 바로 함수를 호출하려고합니다. 이것을 시도하고 싶을 수도 있습니다.

function () {}()

그러나 결과는 SyntaxError입니다.

!함수 앞에 연산자를 사용하면 함수가 표현식으로 취급되므로 다음과 같이 호출 할 수 있습니다.

!function () {}()

이는 또한이 경우에, 함수의 리턴 값의 부울 반대 반환 true때문 !undefined이다 true. 실제 리턴 값이 호출의 결과가되도록하려면 다음과 같이하십시오.

(function () {})()

28
누가 이것을 필요로합니까?
안드레이

13
이것은 질문에 대한 사례를 설명 하는 유일한 대답입니다.
안드레이

14
두 번째 코드 샘플이 유효한 JavaScript가 아닙니다. 의 목적은 !함수 선언을 함수 표현식으로 바꾸는 것입니다.
Skilldrick

8
@Andrey 부트 스트랩 트위터는 모든 자바 스크립트 (jQuery) 플러그인 파일에서 이것을 사용합니다. 다른 사람들도 같은 질문을 할 수 있도록이 설명을 추가하십시오.
Anmol Saraf

2
d3.js는 또한 !function문법 을 사용 합니다
Kristian

65

airbnb JavaScript 가이드! 에 표시된 함수 호출 에 사용 하기에 좋은 점이 있습니다

일반적으로이 기술을 나중에 연결되는 별도의 파일 (일명 모듈)에서 사용하기위한 아이디어입니다. 여기서주의해야 할 점은 새 파일을 새 줄에 넣는 도구에 의해 파일이 연결되어 있어야한다는 것입니다 (어쨌든 대부분의 연결 도구의 일반적인 동작). 이 경우, !이전에 연결된 모듈에서 세미콜론이 누락 된 경우 오류를 피하는 데 도움이되지만, 걱정없이 순서에 상관없이 유연하게 사용할 수 있습니다.

!function abc(){}();
!function bca(){}();

와 동일하게 작동합니다

!function abc(){}();
(function bca(){})();

하나의 문자를 저장하고 임의의 모양이 더 좋습니다.

그리고 그 방법 중 하나로 +, -, ~, void당신은 그들이 다르게 행동 것이라고 함수에서 반환하는 것을 사용하는 경우 사업자는 확실히 함수를 호출하는 측면에서, 같은 효과가 있습니다.

abcval = !function abc(){return true;}() // abcval equals false
bcaval = +function bca(){return true;}() // bcaval equals 1
zyxval = -function zyx(){return true;}() // zyxval equals -1
xyzval = ~function xyz(){return true;}() // your guess?

그러나 하나의 파일 하나의 모듈 코드 분리에 IIFE 패턴을 사용하고 최적화를 위해 concat 도구를 사용하면 (한 줄 하나의 파일 작업을 수행함) 구성

!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()

첫 번째 코드 샘플과 마찬가지로 안전한 코드 실행을 수행합니다.

이것은 JavaScript ASI가 작업을 수행 할 수 없기 때문에 오류를 발생시킵니다.

!function abc(/*no returns*/) {}()
(function bca() {/*no returns*/})()

단항 연산자에 대한 한 가지 참고 사항은 비슷한 작업을 수행하지만 첫 번째 모듈에서 사용하지 않은 경우에만 해당됩니다. 따라서 연결 순서를 완전히 제어하지 않으면 안전하지 않습니다.

이것은 작동합니다 :

!function abc(/*no returns*/) {}()
^function bca() {/*no returns*/}()

이것은 아닙니다 :

^function abc(/*no returns*/) {}()
!function bca() {/*no returns*/}()

3
실제로 이러한 다른 기호는 동일한 효과가 없습니다. 예, 설명 된대로 함수를 호출 할 수 있지만 동일하지는 않습니다. 다음을 고려하십시오. var foo =! function (bar) {console.debug (bar); }("박쥐"); 어떤 기호를 앞에 놓든 콘솔에 "박쥐"가 표시됩니다. 이제 console.debug ( "foo :", foo);를 추가하십시오. 사용하는 기호에 따라 매우 다른 결과가 나타납니다. ! 항상 바람직하지 않은 리턴 값을 강제합니다. 명확성과 정확성을 위해 ({}) () 구문을 선호합니다.
Carnix

29

명령문이 false로 평가 될 수 있는지 여부를 리턴합니다. 예 :

!false      // true
!true       // false
!isValid()  // is not valid

부울 값을 강제로 두 번 사용할 수 있습니다.

!!1    // true
!!0    // false

따라서 귀하의 질문에보다 직접적으로 대답하려면 :

var myVar = !function(){ return false; }();  // myVar contains true

편집 : 함수 선언을 함수 표현식으로 변경하면 부작용이 있습니다. 예를 들어 다음 코드는 필수 식별자 (또는 함수 이름 ) 가없는 함수 선언으로 해석되므로 유효하지 않습니다 .

function () { return false; }();  // syntax error

6
명확하게 호출하기 위해 즉시 호출 된 함수와 함께 할당을 사용하려는 독자에게는 명확성을 기하기 위해 예제 코드 var myVar = !function(){ return false; }()!유사하게 생략 될 수 var myVar = function(){ return false; }()있으며 함수가 올바르게 실행되고 반환 값은 변경되지 않습니다.
Mark Fox

1
분명히 논리 연산자가 아니기 때문에 한 번만 부울로 강제 변환 할 수 있습니다 . ! 0 = true이고! 1 = false입니다. 자바 스크립트 축소를 목적으로, 당신은 대체 할 것 true!0false함께 !1. 2 ~ 3자를 저장합니다.
Triynko

9

우리가 자바 스크립트 축소를 할 때 데이터 바이트를 저장하는 것입니다.

아래의 익명 기능을 고려하십시오.

function (){}

위의 내용을 자체 호출 기능으로 만들려면 일반적으로 위의 코드를 다음과 같이 변경합니다.

(function (){}())

이제 함수를 호출하는 데 필요한 함수 끝에 (,)추가하는 것 외에 두 개의 추가 문자 를 추가 ()했습니다. 축소 과정에서 일반적으로 파일 크기를 줄이는 데 중점을 둡니다. 위 함수를 다음과 같이 쓸 수도 있습니다.

!function (){}()

여전히 두 가지 모두 자체 호출 기능이며 바이트도 절약합니다. 2 개의 문자 대신에 (,)한 문자 만 사용했습니다.!


1
이것은 종종 축소 된 js에서 이것을 볼 수 있기 때문에 도움이됩니다.
이름에 대한

5

! 논리 NOT 연산자이며, 반대 방향으로 무언가를 뒤집는 부울 연산자입니다.

함수 앞에 BANG (!) 을 사용하여 호출 된 함수의 괄호를 무시할 수는 있지만 여전히 리턴을 반전 시키므로 원하는 결과가 아닐 수도 있습니다. IEFE의 경우와 마찬가지로 undefined를 반환 하며,이 값은 반전되면 부울 true가됩니다.

대신 필요한 경우 닫는 괄호와 BANG ( ! )을 사용하십시오.

// I'm going to leave the closing () in all examples as invoking the function with just ! and () takes away from what's happening.

(function(){ return false; }());
=> false

!(function(){ return false; }());
=> true

!!(function(){ return false; }());
=> false

!!!(function(){ return false; }());
=> true

작동하는 다른 연산자 ...

+(function(){ return false; }());
=> 0

-(function(){ return false; }());
=> -0

~(function(){ return false; }());
=> -1

결합 연산자 ...

+!(function(){ return false; }());
=> 1

-!(function(){ return false; }());
=> -1

!+(function(){ return false; }());
=> true

!-(function(){ return false; }());
=> true

~!(function(){ return false; }());
=> -2

~!!(function(){ return false; }());
=> -1

+~(function(){ return false; }());
+> -1

5

느낌표는 모든 함수가 항상 부울을 반환하도록합니다.
최종 값은 함수에 의해 반환 된 값의 부정입니다.

!function bool() { return false; }() // true
!function bool() { return true; }() // false

!위의 예제에서 생략 하면 SyntaxError가 됩니다.

function bool() { return true; }() // SyntaxError

그러나 이것을 달성하는 더 좋은 방법은 다음과 같습니다.

(function bool() { return true; })() // true

이것은 올바르지 않습니다. !런타임이 함수를 구문 분석하는 방식을 변경합니다. 런타임이 함수를 선언이 아닌 함수 표현식으로 처리합니다. 이를 통해 개발자는 ()구문을 사용하여 즉시 함수를 호출 할 수 있습니다 . !함수 표현식을 호출 한 결과에 자체 (즉, 부정)도 적용됩니다.
벤 애스턴

3

IIFE를 작성하는 또 다른 방법 (즉시 호출 된 함수 표현식).

다른 글쓰기 방법-

(function( args ) {})()

와 동일

!function ( args ) {}();

정확히 같은 것은 아닙니다. 두 번째 형식은 함수 호출의 결과를 무효화 한 다음 값을 할당하지 않으므로 버립니다. 나는 더 명확한 (function (args) {...})()구문을 선호하고 그 !function양식을 축소 및 난독 처리 도구로 남겨두고 싶습니다 .
Tobias

-1

! 결과적으로 예상되는 모든 것을 부정 (반대)합니다.

var boy = true;
undefined
boy
true
!boy
false

호출 할 때 boy결과는 true나오지만 !호출 할 때 를 추가하는 순간 boy, 즉 !boy결과는 다음과 같습니다 false. 즉 , NotBoy 를 의미 하지만 이번에는 기본적으로 부울 결과 true또는 false입니다.

그것은 !function () {}();표현식에서 발생하는 것과 똑같은 일이며 , 실행 function () {}();하면 오류 만 표시하지만 표현식 !바로 앞에 추가 function () {}();하면 반대의 결과 function () {}();true됩니다. 아래에서 예를 볼 수 있습니다.

function () {}();
SyntaxError: function statement requires a name
!function () {}();
true
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.