メソッド、this、undefined

7376 ワード

学習グループでは、JavaScriptのthisに関する質問がありました.以前そうしようと思ってスキップした部分ですが、今回は完全に分かりました.
function makeUser() {
  return {
    name: "John",
    ref: this
  };
};

let user = makeUser();

alert( user.ref.name ); // Error: Cannot read property 'name' of undefined
上記の例(ソース:https://ko.javascript.info/object-methods)のuser.これはrefが定義されていない理由が何なのかについての内容です.
1)関数を呼び出すとき、関数がどのように呼び出されるか(グローバルから呼び出されるか、オブジェクトの内部から呼び出されるか)は、この関数にバインドするオブジェクトを動的に決定します.
2)デフォルトでは、グローバル関数と内部関数(関数で宣言された関数)のthisがグローバルオブジェクトにバインドされます.したがって、グローバル関数とその内部関数のthisはグローバルオブジェクトになります.
(グローバル変数はグローバルオブジェクトのプロパティであり、グローバル関数はグローバルオブジェクトのメソッドである.)
var x = 1;
function foo(){
    console.log('hi')
}

// 프로퍼티로 접근가능
window.x

// 프로퍼티로 접근 가능한 메서드
window.foo()

/*
Global Object

window = {
    ...,
    x: 1,
    foo: function(){
        console.log('hi)
    }        
}
이런 모양.
*/

リファレンス
https://techwell.wooritech.com/docs/languages/javascript/scope-this
)
上記のサンプルコードでは、makeUser関数はグローバル関数です.つまり、makeUserで使用されているthisはグローバルオブジェクトになります.ブラウザ環境では、グローバルオブジェクトはwindowオブジェクトであり、これはwindowオブジェクトを意味します.
3)これはwindowオブジェクトですが、出力が定義されていないのは「use strict」厳格モードのためです.既存の(ES 5)コンストラクション関数を呼び出したときにnewキーを忘れた場合、グローバルオブジェクト(ブラウザのwindowオブジェクト)を参照してグローバルオブジェクトを変更します.
function myConstructor() {
    this.a = 'foo';
    this.b = 'bar';
}

myInstance = new myConstructor(); 
// all cool, all fine. a and b were created in a new local object
myBadInstance = myConstructor(); 
// oh my gosh, we just created a, and b on the window object
このような混同を防止するために、ここでグローバルオブジェクトが表示された場合、undefinedを使用してグローバルオブジェクトを置き換えます.
ソース:https://stackoverflow.com/questions/9822561/why-is-this-in-an-anonymous-function-undefined-when-using-strict
4)
function makeUser() {
  return {
    name: "John",
    ref() {
      return this;
    }
  };
};

let user = makeUser();

alert( user.ref().name ); // John
オブジェクトとして宣言されたpropertyの関数、すなわちメソッドのthisは、メソッド(自身)をpropertyのオブジェクトとして表す.
https://hyojin96.tistory.com/entry/%EA%B0%9D%EC%B2%B4%EC%9D%98-%EB%A9%94%EC%84%9C%EB%93%9C%EB%A5%BC-%ED%98%B8%EC%B6%9C%ED%95%A0-%EB%95%8C-this