JS の中括弧には 4 つの意味関数があります
セマンティクス 1、複合ステートメントを整理します。これは最も一般的なものです
if( 条件 ) {
//...
}else {
//...
}
for() {
//...
}
セマンティック 2、オブジェクト リテラル宣言
var obj = {
名前 : 'jack',
年齢 : 23
}; >
全体は代入文であり、{name:'jack',age:23} が式です。
セマンティック 3、関数または関数リテラルを宣言
function f1(){
//...
}
var f2 = function(){
//...
}
f1 と非 f2 の違いは、前者が構文解釈期間にあり、後者が実行時にあることです。違いは、関数を呼び出すコードが関数定義の後にある場合は違いがありませんが、関数を呼び出すコードが関数定義の前にある場合は f1 を呼び出すことはできますが、f2 はエラーを報告して、その旨を通知します。 f2は定義されていません。
セマンティクス 4、構造化例外処理の構文シンボル
try {
//...
}catch( ex ){
//...
}やっと{
//...
}
ここの中括弧と一致するステートメント (意味 1) の間に違いがあります。中括弧内のステートメントが 1 つだけの場合は、if/else/ で中括弧を省略できます。 for など。ただし、try/catch/finally は省略できません。
私は長い間次のコードに苦労していました
function(){}() //匿名関数はすぐに実行され、構文解析期間がレポートされます
{}.constructor //オブジェクト リテラルのコンストラクターを取得します、そして構文解析期間はエラーを報告します
不可解なのは、なぜ [].constructor がこのように書かれているのにエラーを報告しないのかということです。 1 つは、 の直接の値を取得したいコンストラクターです。 1 つはオブジェクトで、もう 1 つは配列の直接値を取得したい単なるコンストラクターです。
もちろん、受信する変数を追加してもエラーは発生しません
var c = {}.constructor;
と同じ状況
var fn = function(){}()、エラーは報告されません。
実際に問題を引き起こしているのは js の「ステートメントの優先順位」です。つまり、{} はオブジェクト リテラル (セマンティック 2) や宣言された関数のセマンティックではなく、複合ステートメント ブロック (セマンティック 1) として理解されます。 (意味3)。
function(){}()、中括弧は複合文として理解されます。当然、前の function() 宣言関数の構文は不完全であるため、構文解析中にエラーが発生します。
{}.constructor では、中括弧は複合ステートメントとして理解され、中括弧の後にドット演算子が続きます。ドット演算子の前に適切なオブジェクトがない場合は、当然エラーが報告されます。
修正はよく知られています: 強制演算子を追加します ()
(function(){})(), (function(){});//強制的に関数として理解される (意味論 3)、「Function ()」は関数の実行を意味します。つまり、関数は宣言の直後に実行されます。
({}).constructor //({}) は、中括弧をオブジェクト リテラルとして強制的に解釈します (意味 2)。「Object.xx」は、当然のことながら、オブジェクトのメンバーを取得することを意味します。以下のドット演算子は正常に実行できます。