「new」演算子を使用してオブジェクトを作成するときに、括弧を省略できますか?


229

この方法でオブジェクトが作成されるのを見てきました。

const obj = new Foo;

しかし、オブジェクトを作成するときに括弧はオプションではないと思いました:

const obj = new Foo();

オブジェクトを作成する以前の方法は有効であり、ECMAScript標準で定義されていますか?以前のオブジェクト作成方法と後者の方法に違いはありますか?どちらが優先されますか?



更新された参照:ECMAScript 2017§12.3.3新しいOpertator
RobG 2017

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(page 75)


6
JSLintが括弧の使用を推奨するのはなぜですか?
Randomblue 2011

11
私はそれがより一貫していると考えられていると思います。
ダニエル・ヴァッサロ

12
多くのJavaScript開発者が「ツール(JSLint)が括弧を使用するように指示した」という理由だけで括弧を使用していること、特にdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Guideの例を考慮すると興味深いと思います/…、「<expletive>言語を発明した人たち」からはnew Class、パラメーターなしのコンストラクターで括弧を使用しないでください。これが「意見」を綴らない場合、私は何をするのかわかりません...
ack

52
@ackまあ、言語の発明者が彼らの言語の特定の機能を紹介するのを見ないのは奇妙でしょう(この場合、コンストラクタで括弧を省略するオプション)。彼らがこの機能を追加していなかったとしても、そもそもそれを使用すべきかどうかを尋ねることはないでしょう。これを使用しない実際的な理由は次のとおりnew Object.func()ですnew Object().func()。と同等ではありません。常に括弧を含めることにより、この間違いをする可能性がなくなります。
nmclean 2014

2
あなたがミスをする可能性を排除したいなら、あなたは使うべき(new Object).func()です。しかし、==vsのように、余分な括弧と等号を使用することを検討し===ます。これは、言語を学習しないための悪い言い訳です。
Jean Vincent

78

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        
╚════════════╩═════════════════════════════╩═══════════════╩═════════════╝

この表から、次のことがわかります。

  1. 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))()

    同じロジックを… [ … ]オペレーターに適用できます。

  2. new Foo持っている右から左結合性をとするためにnew Foo()、「関連性」は適用されません。実際には違いはないと思います。追加情報については、この SOの質問を参照してください


どちらが優先されますか?

それをすべて知っていると、それnew Foo()が好ましいと仮定できます。


4
最後に、実際に質問に答えて微妙な違いを指摘する人!
gcampbell 16

わあ、ありがとう。他の言語を思い出すen.wikipedia.org/wiki/Brainfuck
John Henckel

よく説明されていますが、new Foo()が優先される理由を正確に示していますnew Foo。これまでのベストアンサー。
CodeLama

素晴らしい答え、優先順位表とそれに付随する説明は、それを完全に明確にします。うれしいあなたはそれはそれは、書き込みに大丈夫になり方法を説明するnew Object().something()だけでなく、(new Object()).something()
LittleTiger 2016

1
素晴らしい説明ですが、結論には同意しませんが、あなたの言語を知っていれば、括弧を使用しなくても結構です。ところで、JSの優先順位がわからない場合は(new Date).toString()、同じ文字数で、より明示的に使用することもできますnew Date().toString
Jean Vincent

14

「new」演算子を使用している場合、違いはないと思います。次の2行のコードは同じではないため、この習慣に注意してください。

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 2017


8

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

ES5とES3でも適切に定義されています-「コンストラクターで[[Construct]]内部メソッドを呼び出して、引数を指定しない(つまり、引数の空のリスト)の結果を返します。」
Benjamin Gruenbaum 2014年

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.