이런 식으로 객체가 생성되는 것을 보았습니다.
const obj = new Foo;
그러나 객체를 만들 때 괄호는 선택 사항이 아니라고 생각했습니다.
const obj = new Foo();
이전의 객체 생성 방법이 ECMAScript 표준에 유효하고 정의되어 있습니까? 이전의 객체 생성 방식과 이후의 방식간에 차이점이 있습니까? 하나는 다른 것보다 선호됩니까?
new a.b()new a().b()a.ba
이런 식으로 객체가 생성되는 것을 보았습니다.
const obj = new Foo;
그러나 객체를 만들 때 괄호는 선택 사항이 아니라고 생각했습니다.
const obj = new Foo();
이전의 객체 생성 방법이 ECMAScript 표준에 유효하고 정의되어 있습니까? 이전의 객체 생성 방식과 이후의 방식간에 차이점이 있습니까? 하나는 다른 것보다 선호됩니까?
new a.b()new a().b()a.ba
답변:
인용 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)
new Class매개 변수없는 생성자에는 괄호를 사용하지 않습니다 . 이것이 '발견 된'철자가 아닌 경우, 나는 무엇을하는지 모르겠다.
new Object.func()는 다음과 같습니다 new Object().func(). 항상 괄호를 포함하면이 실수를 할 가능성이 없어집니다.
(new Object).func(). 그러나 ==vs와 같이 여분의 괄호와 여분의 등호를 사용 ===하는 것은 언어를 배우지 못하는 것에 대한 나쁜 변명을 고려하는 것입니다.
둘 사이에는 차이점이 있습니다.
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 … ║
╚════════════╩═════════════════════════════╩═══════════════╩═════════════╝
이 테이블에서 다음과 같습니다.
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))()
… [ … ]운영자 에게 동일한 논리를 적용 할 수 있습니다 .
new Foo한 오른쪽에서 왼쪽으로 연관성 및 위해 new Foo()"연관성"은 적용되지 않습니다. 실제로는 아무런 차이가 없다고 생각합니다. 자세한 내용은 이 SO 질문을 참조하십시오
하나는 다른 것보다 선호됩니까?
모든 것을 알면 new Foo()선호되는 것으로 가정 할 수 있습니다 .
new Foo()선호해야하는 이유를 정확하게 제시 합니다 new Foo. 지금까지 가장 좋은 답변입니다.
new Object().something()와 글쓰기가 어떻게되는지 설명해 주셔서 감사합니다 (new Object()).something().
(new Date).toString(), 동일한 문자 수 및보다 명시적인을 사용할 수도 있습니다 new Date().toString.
전달할 인수가 없으면 괄호는 선택 사항입니다. 그것들을 생략하면 구문 설탕 일뿐입니다.
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