2017-06-08 5 views
0

私はJavaScriptを学んでおり、オブジェクトの中に2つのクラスを定義したいと思います。 2番目のクラスは1番目のクラスから派生しています。オブジェクトはいつ完全に定義されますか?

それは次のようになります。そして、

Uncaught ReferenceError: foo is not defined

、私は複数の部分にクラスを分割しようとしました::

let foo = { 
 
    bar: (function() { 
 
     let bar_msg = ''; 
 

 
     class bar { 
 
      constructor(msg) { 
 
       bar_msg = msg; 
 
      } 
 
     } 
 
     return bar; 
 
    }()), 
 
    baz: (function() { 
 
     let baz_msg = ''; 
 

 
     class baz extends foo.bar { 
 
      constructor(msg) { 
 
       super(); 
 
       baz_msg = msg; 
 
      } 
 
     } 
 
     return baz; 
 
    }()) 
 
};

エラーメッセージを

let foo = {}; 
 

 
foo.bar = (function() { 
 
    let bar_msg = ''; 
 

 
    class bar { 
 
     constructor(msg) { 
 
      bar_msg = msg; 
 
     } 
 
    } 
 
    return bar; 
 
}()); 
 

 
foo.baz = (function() { 
 
    let baz_msg = ''; 
 

 
    class baz extends foo.bar { 
 
     constructor(msg) { 
 
      super(); 
 
      baz_msg = msg; 
 
     } 
 
     msg() { 
 
      return baz_msg; 
 
     } 
 
    } 
 
    return baz; 
 
}()); 
 

 
let b = new foo.baz('hi!'); 
 
console.log(b.msg());

これは機能します。

私の質問は次のとおりです。違いは何ですか?私はキーワードについて考えていないので、私はいくつかのGoogleの検索結果を表示することはできません。

答えて

1

オブジェクトは、「完全に」そうのような値をあなたがそれを宣言したときに定義し、それを割り当てることです:

var foo = 'bar'; 

あなたは変数を宣言したが、任意の値に割り当てないことがあります。

var foo; 

あなたがそれにアクセスしようとすると、それはあなたに未定義を与えます。また、宣言されていない変数に値を割り当てることがあります。

foo = 'bar'; 

とJavaScriptを自動的にグローバル変数fooを作成します。一度も宣言されていない変数や暗黙的に宣言された変数にアクセスしようとすると(例えばfoo = 'bar')エラーが発生します。あなたの最初のコードで

console.log(iDoNotExist); // will throw an error! 

、クラスbazに、独自のスコープでfooを見つけることができませんでしたので、それがグローバルスコープに行きます。しかし、それもグローバルスコープでは利用できず、明示的にも暗黙的にも宣言されていないため、エラーが発生します。

2番目のコードでは、fooを明示的に宣言し、それをオブジェクトに割り当て、その直後にプロパティbarを追加しました。 fooが宣言された後に記述されたコードは、barfooに割り当てると、bazというクラスがfoo.barを拡張しようとするなど、アクセスできるようになります。 fooまたはfoo.barを拡張しようとしたコードがfooの定義の後に書かれているとします。エラーが発生します。例えば、以下のスニペットを参照してください:

class baz extends foo { 
 
     constructor(msg) { 
 
      super(); 
 
      baz_msg = msg; 
 
     } 
 
     msg() { 
 
      return baz_msg; 
 
     } 
 
    } 
 

 
let foo = {}; 
 

 
let b = new foo.baz('hi!');

要約すると、あなたはfooのアクセシビリティのための違いを取得します。最初の変数では、明示的にも暗黙的にも定義される前にアクセスしようとすると、エラーが発生します。2番目の変数では、それを宣言して値に割り当ててからアクセスしますが、これは完全に合法です。

+0

私はそれが十分な情報ではないと思う。私はもう一度コードをテストしたので、 'let foo = {bar(){console.log(typeof foo); }}; '。私が 'foo.bar()'を呼び出すと、それはログに記録されます: 'object'。だから、あなたの答えは間違っていた – Vayne

+0

'foo'宣言の内側で、または内側でfoo.barを呼び出しましたか? fooの中でbar関数を呼び出してみてください。 'foo'でクラス' baz'を拡張しようとすると、未定義となります。まだ宣言されていないので、まだ利用できません。 –

+0

私はより明確に答えを更新しました。 –

関連する問題