まず例を見てみましょう:
<script> var a = {n:1}; var b = a; a.x = a = {n:2}; console.log(a.x);// --> undefined console.log(b.x);// --> [object Object] </script>
上記の例は単純に見えますが、結果は理解するのが簡単ではなく、人々を混乱させやすいです - 「a.x はオブジェクト a を指しているのではありませんか? なぜ log(a.x) は未定義ですか?」、「B.x はオブジェクト a を指していませんか?」 a.x と同じである必要がありますか? ログに 2 つのオブジェクトがあるのはなぜですか?"
もちろん、最初にその理由や仕組みが理解できれば、読み続ける必要はありません。
JS 参照型の「割り当て」がどのように機能するかをさらに理解するために、この単純なコードの作業手順を分析してみましょう。
まずは
var a = {n:1};
var b = a;
このステップは理解しやすいので、非常に重要なコードの次の行に進みます。
a.x = a = {n:2};
js での代入演算の順序は常に右から左であることがわかっていますが、「.」が最も優先度の高い演算子であるため、このコード行は最初に a.x を「計算」します。
これがこの時点で起こったことです - a が指すオブジェクト {n:1} には新しい属性 x があります (ただし、この x は未定義です):
図からわかるように、b は a と同様にオブジェクト A を指しているため、a.x を使用して A の x 属性を表すことに加えて、当然のことながら b.x を使用してそれを表すこともできます。
次に、「右から左」の代入操作シーケンスに従って、最初に a={n:2} が実行されます。このとき、a が指すオブジェクトは変更され、新しいオブジェクト {n:2} になります。オブジェクト B) の場合:
その後、a.x=a を実行し続けます。多くの人は、これを「オブジェクト B も新しい属性 x を追加し、オブジェクト B 自体をポイントしている」と考えるでしょう。
しかし、これは実際には当てはまりません。js は最初に a.x をすでに計算しているため、a.x がオブジェクト A の x であることがすでに分析されているため、値を a.x に代入するために戻ってきた場合、この a.x を次のように解析します。オブジェクト B の x。
したがって、a.x=a は、オブジェクト A の属性 x がオブジェクト B を指していると理解される必要があります。
そうすれば、この時点で結果は明らかです。 console.log(a.x) の場合、 a はオブジェクト B を指しますが、オブジェクト B には属性 x がありません。大丈夫です。オブジェクトのプロパティを探すとき、JavaScript は指定された名前のプロパティが見つかるまでプロトタイプ チェーンをたどります。しかし、検索がプロトタイプ チェーンの先頭 (つまり Object.prototype) に到達しても、指定されたプロパティ B.prototype.x はまだ見つからず、当然のことながら undefined が出力されます。
console.log(b.x) の場合、b.x はオブジェクト B を指すオブジェクト A の x 属性を表すため、当然 [object Object] が出力されますが、ここでの [object Object] はオブジェクトの意味ではありません。オブジェクトの文字列形式は、「[object Object]」という形式で、Object オブジェクトの toString() メソッドを暗黙的に呼び出します。したがって、[オブジェクト オブジェクト] は単なるオブジェクト
を表します。以上がこの記事の全内容です。皆さんに気に入っていただければ幸いです。