レッスンに戻る

オブジェクトリテラル内で「this」を使用

重要度: 5

ここでは関数makeUserがオブジェクトを返します。

そのrefにアクセスするとどうなりますか?なぜですか?

function makeUser() {
  return {
    name: "John",
    ref: this
  };
}

let user = makeUser();

alert( user.ref.name ); // What's the result?

回答:エラーです。

試してみる

function makeUser() {
  return {
    name: "John",
    ref: this
  };
}

let user = makeUser();

alert( user.ref.name ); // Error: Cannot read property 'name' of undefined

これはthisを設定するルールはオブジェクト定義を見ないためです。呼び出しの瞬間だけ関係します。

ここではmakeUser()内のthisの値はundefinedです。ドット記法を使用してメソッドとして呼び出されるのではなく、関数として呼び出されるためです。

thisの値は関数全体に対して1つです。コードブロックやオブジェクトリテラルはそれに影響を与えません。

そのため、ref: thisは実際には関数の現在のthisを取得します。

関数を書き直して、同じthisundefined値で返すことができます

function makeUser(){
  return this; // this time there's no object literal
}

alert( makeUser().name ); // Error: Cannot read property 'name' of undefined

ご覧のとおり、alert( makeUser().name )の結果は、前の例のalert( user.ref.name )の結果と同じです。

これが逆の場合を以下に示します。

function makeUser() {
  return {
    name: "John",
    ref() {
      return this;
    }
  };
}

let user = makeUser();

alert( user.ref().name ); // John

今度は機能します。なぜなら、user.ref()はメソッドだからです。また、thisの値はドット.より前のオブジェクトに設定されます。