“new”연산자를 사용하여 객체를 만들 때 괄호를 생략 할 수 있습니까?


229

이런 식으로 객체가 생성되는 것을 보았습니다.

const obj = new Foo;

그러나 객체를 만들 때 괄호는 선택 사항이 아니라고 생각했습니다.

const obj = new Foo();

이전의 객체 생성 방법이 ECMAScript 표준에 유효하고 정의되어 있습니까? 이전의 객체 생성 방식과 이후의 방식간에 차이점이 있습니까? 하나는 다른 것보다 선호됩니까?



업데이트 된 참조 : ECMAScript 2017 §12.3.3 새로운 Opertator .
RobG

TL; DR : 전자의 경우 에는 먼저 액세스하는 반면, 후자의 경우 먼저 새로운 것이 생성 된다는 점 에서 다른 점에 유의 하십시오 . new a.b()new a().b()a.ba
앤드류

답변:


238

인용 David Flanagan 1 :

특별한 경우, new연산자의 경우에만 JavaScript는 함수 호출에 인수가없는 경우 괄호를 생략 할 수 있도록하여 문법을 단순화합니다. new연산자를 사용하는 몇 가지 예는 다음과 같습니다 .

o = new Object;  // Optional parenthesis omitted here
d = new Date();  

...

개인적으로, 생성자가 인수를 취하지 않아도 항상 괄호를 사용합니다.

또한 괄호를 생략하면 JSLint 가 감정을 상하게 할 수 있습니다. 그것은보고 Missing '()' invoking a constructor하고 도구가 괄호 생략을 허용하는 옵션이없는 것 같습니다.


1 David Flanagan : JavaScript the Definitive Guide : 4th Edition (페이지 75)


6
JSLint가 괄호 사용을 권장하는 이유는 무엇입니까?
Randomblue

11
나는 그것이 더 일관성있는 것으로 간주된다고 생각합니다.
Daniel Vassallo

12
많은 개발자들이 "툴 (JSLint)이 그렇게하도록 지시했기 때문에"괄호를 사용한다는 사실이 흥미 롭다. 특히 developer.mozilla.org/en-US/docs/Web/JavaScript/Guide 의 예제를 고려하면 " ... <expletive> language를 발명 한 사람들"의 new Class매개 변수없는 생성자에는 괄호를 사용하지 않습니다 . 이것이 '발견 된'철자가 아닌 경우, 나는 무엇을하는지 모르겠다.
ack

52
@ack 글쎄, 언어의 발명자들이 언어의 특정 기능을 보여 주지 않는 것은 이상한 일입니다 (이 경우 생성자에서 괄호를 생략하는 옵션). 그들이 기능을 추가하지 않았다면, 우리는 기능을 처음에 사용해야하는지 묻지 않을 것입니다. 사용하지 않는 실질적인 이유 new Object.func()는 다음과 같습니다 new Object().func(). 항상 괄호를 포함하면이 실수를 할 가능성이 없어집니다.
nmclean

2
실수 할 가능성을 없애려면을 사용해야합니다 (new Object).func(). 그러나 ==vs와 같이 여분의 괄호와 여분의 등호를 사용 ===하는 것은 언어를 배우지 못하는 것에 대한 나쁜 변명을 고려하는 것입니다.
Jean Vincent

78

둘 사이에는 차이점이 있습니다.

  • new Date().toString() 완벽하게 작동하고 현재 날짜를 반환합니다
  • new Date.toString()" TypeError : Date.toString은 생성자가 아닙니다 "발생

때문에이 발생 new Date()하고 new Date다른 우선 순위를 가지고있다. MDN 에 따르면 우리가 관심을 갖고있는 JavaScript 연산자 우선 순위 테이블의 일부는 다음과 같습니다.

╔════════════╦═════════════════════════════╦═══════════════╦═════════════╗
 Precedence         Operator type         Associativity   Operators  
╠════════════╬═════════════════════════════╬═══════════════╬═════════════╣
     18      Member Access                left-to-right   .        
             Computed Member Access       left-to-right    [  ]    
             new (with argument list)     n/a            new  (  ) 
╠════════════╬═════════════════════════════╬═══════════════╬═════════════╣
     17      Function Call                left-to-right   (  )     
             new (without argument list)  right-to-left  new        
╚════════════╩═════════════════════════════╩═══════════════╩═════════════╝

이 테이블에서 다음과 같습니다.

  1. new Foo() 보다 우선 순위가 높다 new Foo

    new Foo().연산자 와 우선 순위가 같습니다

    new Foo.운영자 보다 한 수준 낮은 우선 순위를 가짐

    new Date().toString() 다음과 같이 평가되기 때문에 완벽하게 작동합니다. (new Date()).toString()

    new Date.toString()" TypeError : Date.toString is a constructor " .이 발생합니다 new Date( "Function Call" 보다 우선 순위가 높음 ).(new (Date.toString))()

    … [ … ]운영자 에게 동일한 논리를 적용 할 수 있습니다 .

  2. new Foo오른쪽에서 왼쪽으로 연관성 및 위해 new Foo()"연관성"은 적용되지 않습니다. 실제로는 아무런 차이가 없다고 생각합니다. 자세한 내용은 SO 질문을 참조하십시오


하나는 다른 것보다 선호됩니까?

모든 것을 알면 new Foo()선호되는 것으로 가정 할 수 있습니다 .


4
마지막으로 실제로 질문에 대답하고 미묘한 차이를 지적하는 사람!
gcampbell

와우 감사합니다. 다른 언어를 생각 나게 en.wikipedia.org/wiki/Brainfuck
존 헨켈

잘 설명하고, 왜 new Foo()선호해야하는 이유를 정확하게 제시 합니다 new Foo. 지금까지 가장 좋은 답변입니다.
CodeLama

멋진 답변, 우선 순위 표 및 함께 제공되는 설명을 통해 명확하게 알 수 있습니다. 글쓰기 new Object().something()와 글쓰기가 어떻게되는지 설명해 주셔서 감사합니다 (new Object()).something().
LittleTiger

1
대단한 설명이지만 나는 결론에 동의하지 않지만 괄호를 사용하지 않으면 언어를 잘 알고 있다고 생각합니다. BTW JS 우선 순위를 모른다면 (new Date).toString(), 동일한 문자 수 및보다 명시적인을 사용할 수도 있습니다 new Date().toString.
Jean Vincent

14

"새"연산자를 사용할 때 차이가 없다고 생각합니다. 이 두 줄의 코드는 동일하지 않으므로이 습관에주의하십시오.

var someVar = myFunc; // this assigns the function myFunc to someVar
var someOtherVar = myFunc(); // this executes myFunc and assigns the returned value to someOtherVar

1
세미콜론을 생략하는 습관이 있다면 더욱 문제가됩니다. ;-)
RobG

13

전달할 인수가 없으면 괄호는 선택 사항입니다. 그것들을 생략하면 구문 설탕 일뿐입니다.


8
나는 구문 소금이라고 말하지만 ymmv.
Thomas Eding

필요하지 않은 것을 추가하면 구문 설탕이라고 말할 수 있습니다. :)
Cozzbie

8

https://people.mozilla.org/~jorendorff/es6-draft.html#sec-new-operator-runtime-semantics-evaluation

다음은 두 변형이 작동하는 방식을 정의하는 ES6 사양의 일부입니다. 괄호 없음 변형은 빈 인수 목록을 전달합니다.

흥미롭게도, 두 형태는 다른 문법적 의미를 가지고 있습니다. 결과의 멤버에 액세스하려고 할 때 나타납니다.

new Array.length // fails because Array.length is the number 1, not a constructor
new Array().length // 0

ES5와 ES3에서도 잘 정의되어있다. "인자에서 [[Construct]] 내부 메소드를 호출 한 결과를 반환하고, 인자를 제공하지 않는다 (빈 인자 목록).
Benjamin Gruenbaum

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.