この方法でオブジェクトが作成されるのを見ました:
const obj = new Foo;
しかし、オブジェクトを作成するとき、括弧はオプションではないと考えました。
const obj = new Foo();
オブジェクトを作成する前者の方法は有効で、ECMAScript標準で定義されていますか?前者のオブジェクト作成方法と後者の方法に違いはありますか?一方が他方よりも優先されますか?
引用 David Flanagan1:
特別な場合として、
new
演算子の場合のみ、JavaScriptは関数呼び出しに引数がない場合に括弧を省略できるようにして、文法を簡素化します。new
演算子を使用した例を次に示します。_o = new Object; // Optional parenthesis omitted here d = new Date(); ...
_
個人的には、コンストラクタが引数を取らない場合でも、常に括弧を使用します。
さらに、 JSLint は、括弧を省略すると感情を傷つける可能性があります。 Missing '()' invoking a constructor
を報告しますが、括弧の省略を許容するツールのオプションはないようです。
1 デイビッド・フラナガン: JavaScript決定版ガイド:第4版 (75ページ)
2つの間に違いがあります。
new Date().toString()
は完全に機能し、現在の日付を返しますnew Date.toString()
throws "TypeError:Date.toString is not constructor"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()
throws "TypeError:Date.toString is not a constructor" .
はnew Date
よりも優先順位が高い(および「関数よりも高い」 Call ")と式は(new (Date.toString))()
として評価されます
同じロジックを… [ … ]
演算子に適用できます。
new Foo
にはright-to-leftの結合性があり、new Foo()
には「結合性」は適用できません。実際には違いはないと思います。詳細については、 this SO question
一方が他方よりも優先されますか?
すべてを知っているので、new Foo()
が優先されると仮定できます。
「新しい」演算子を使用している場合、違いはないと思います。これらの2行のコードは同じではないため、この習慣に注意してください。
var someVar = myFunc; // this assigns the function myFunc to someVar
var someOtherVar = myFunc(); // this executes myFunc and assigns the returned value to someOtherVar
渡す引数がない場合、括弧はオプションです。それらを省略することは単なる構文上の砂糖です。
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
2つの間に違いはありません。