この方法でオブジェクトが作成されるのを見てきました。
const obj = new Foo;
しかし、オブジェクトを作成するときに括弧はオプションではないと思いました:
const obj = new Foo();
オブジェクトを作成する以前の方法は有効であり、ECMAScript標準で定義されていますか?以前のオブジェクト作成方法と後者の方法に違いはありますか?どちらが優先されますか?
new a.b()
new a().b()
a.b
a
この方法でオブジェクトが作成されるのを見てきました。
const obj = new Foo;
しかし、オブジェクトを作成するときに括弧はオプションではないと思いました:
const obj = new Foo();
オブジェクトを作成する以前の方法は有効であり、ECMAScript標準で定義されていますか?以前のオブジェクト作成方法と後者の方法に違いはありますか?どちらが優先されますか?
new a.b()
new a().b()
a.b
a
回答:
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(page 75)
new Class
、パラメーターなしのコンストラクターで括弧を使用しないでください。これが「意見」を綴らない場合、私は何をするのかわかりません...
new Object.func()
ですnew Object().func()
。と同等ではありません。常に括弧を含めることにより、この間違いをする可能性がなくなります。
(new Object).func()
です。しかし、==
vsのように、余分な括弧と等号を使用することを検討し===
ます。これは、言語を学習しないための悪い言い訳です。
2つの間に違いがあります。
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
.
演算子よりも1レベル低い優先順位
new Date().toString()
次のように評価されるため、完全に機能します (new Date()).toString()
new Date.toString()
「スロー:Date.toStringはコンストラクタではありませんTypeError例外があるため、」.
より高い優先順位があるnew Date
(と高いし、「関数呼び出し」)および発現評価されると(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
これは、2つのバリアントの動作方法を定義するES6仕様の一部です。括弧なしのバリアントは、空の引数リストを渡します。
興味深いことに、2つの形式には文法上の意味があります。これは、結果のメンバーにアクセスしようとすると発生します。
new Array.length // fails because Array.length is the number 1, not a constructor
new Array().length // 0