JS this


this


今日はJSのthisキーワードについてご紹介します.

What is this?


MDNのthisに関する記事において、JSはこのような説明を行った.
ほとんどの場合、thisの値は関数を呼び出す方法によって決まります.実行時に割り当てに設定することはできません.関数を呼び出すときに異なる場合があります.
実行コンテキスト(global、function、eval)のプロセスは、常に非厳格モードでオブジェクトを参照し、厳格モードでは任意の値であってもよい.
thisの値は、関数を呼び出す方法によって決定され、非厳格モードでは、実行コンテキストが常にthisオブジェクトを参照していることを示します.

グローバルコンテキストのthis


グローバルコンテキストでは、グローバルオブジェクトを参照します.
console.log(this); //window
console.log(this === window); //true

var a = 1;
console.log(this.a); //1
console.log(window.a); //1
console.log(this.a === window.a); //true

関数コンテキストのthis


一般関数

function myFunc() {
     console.log(this);
}
myFunc(); //window

グローバルコンテキストで単純に関数を呼び出すと、関数ではグローバルオブジェクトが参照されます.

オブジェクトからのアプローチ


オブジェクトのメソッドで関数を呼び出すと、呼び出されたオブジェクトが参照されます.
var obj = {
     a: 5,
     objFunc: function() {
     	console.log(this);
     }
}
var obj2 = { a: 10 };
obj2.obj2Func = obj.objFunc;

obj.objFunc(); //obj
obj2.obj2Func(); //obj2

オブジェクトのprototypeメソッドで

var o = {
     a: 5, b: 5,
     func: function() { return this.a + this.b }
}
var p = Object.create(o);
p.a = 2;
p.b = 2;

console.log(p.func()); //4
console.dir(p);

コードでは、pオブジェクトはo.prototypeです.funcに近づいています.o.prototype.funcはこれわあ、これ.bを加算した値を返す.
p.funcを実行して4を返します.funcメソッドはpによって呼び出されるので、pを参照します.
オブジェクトのprototypeメソッドを呼び出す場合、thisはオブジェクトを呼び出すメソッドと同じです.

ジェネレータ

var C = function(b) {
     this.a = b;
}
C.prototype.a = 5;
var o = new C(7);

console.log(o.a);//7
console.dir(o);

コンストラクション関数では、thisはコンストラクション関数が返すオブジェクトです.
説明がちょっと難しい.コードを見てみましょう.
  • ジェネレータ関数Cは、パラメータbをthisとする.aに割り当てる.
  • C.prototype.aを宣言し、5を割り当てる.
  • 7を
  • 生成者関数Cのパラメータとして返したオブジェクトを変数oに割り当てる.
    3.1コンストラクション関数Cが受け入れるパラメータ7はthisである.aの値に設定します.
    3.2ここで、これが対象となるo.コンストラクション関数Cが返すオブジェクトはoであるからである.
  • varo=new C(7)がコンストラクション関数Cを呼び出すと、これはoを参照するため、o.a=7となる.
  • ないぶかんすう


    結論として、内部関数のthisは常にグローバルオブジェクトを参照します.

    一般関数の内部関数

    function outerFunc() {
         function innerFunc() {
         	console.log(this);
         }
         innerFunc();
    }
    
    outerFunc();

    オブジェクトメソッドの内部関数

    var o = {
         outerFunc: function() {
         	innerFunc = function() { console.log(this) };
            innerFunc();
         }
    }
    
    o.outerFunc();

    このアイテムをバインドする関数


    Function.prototypeの方法にはapply,call,bindが存在する.
    この3つの関数の共通点は、ユーザーがこの関数をバインドできるようにすることです.
    今、私は一つ一つ聞いています.

    関数の適用


    MDNのapply関数についての記事では、アプリケーションについてこのように説明している.
    apply()メソッドは、指定されたこの値と配列(または類似の配列オブジェクト)が提供するパラメータ呼び出し関数を使用します.
    apply呼び出し関数は、最初のパラメータとして受信したオブジェクトを呼び出しの関数にバインドし、2番目のパラメータとして受信した配列(類似配列も受け入れる)を呼び出し関数のパラメータとする.
    コードに示すように.
    var o = {
        name: "o",
        objFunc: function() { console.log(this); }
    }
    var b = { name: "b" };
    
    o.objFunc.apply(b);
  • objFuncはoオブジェクトのメソッドであるため、objFuncではoが参照される.
  • bという独立したオブジェクトを作成し、apply関数としてo.objFuncメソッドを呼び出します.
    2.1このときbをapply関数の最初のパラメータとするため、o.objfuncのthisはbにバインドされる.
  • objfuncのこの参照b.
  • applyの2番目のパラメータも使用できます.
    var o = {
        name: "o",
        objFunc: function(name, age) { this.name = name; this.age = age; }
    }
    var b = { name: "b" };
    
    o.objFunc.apply(b, ["a", 1]);
    console.dir(b);

    1.o.objFuncはパラメータnameとageを受け入れ、各パラメータはthisである.nameとthis.ageの値で割り当てる.
    2.bという独立したオブジェクトを作成し、objFuncメソッドをapply関数として呼び出し、bにバインドします.
    3.apply関数に渡される2番目のパラメータの単一配列は、objFuncのパラメータとして順次使用される.
    混同されやすいのは、戻り関数ではなくapply関数呼び出しです.

    呼び出し関数


    call関数はapply関数とよく似ています.
    すべての関数はapply関数と同じですが、2番目のパラメータとして配列を受け入れるのではなく、パラメータリストを受け入れるのは1つだけ違います.
    例えば、apply(this,[1,2,3]);やるべきことを呼び出す(this,1,2,3);つまりやるということです.
    var o = {
        name: "o",
        objFunc: function(name, age) { this.name = name; this.age = age; }
    }
    var b = { name: "b" };
    
    o.objFunc.call(b, "a", 1);
    console.dir(b);

    bind関数


    bindは関数を返し、最初のパラメータとして受信したオブジェクトをその関数にバインドします.次に、2番目のパラメータから順にその関数のパラメータとして入れます.コール関数のようです.
    bind関数は、関数を呼び出すのではなく、関数を返すことに注意してください.
    var o = {
        name: "o",
        oFunc: function(name, age) { this.name = name; this.age = age; }
    }
    var b = { name: "b" };
    
    b.bFunc = o.oFunc.bind(b, "a", 1);
    b.bFunc();
    console.dir(b);

    またbind関数が返す関数には、次の内部プロシージャがあります.

    [TargetFunction]:バインドされた関数のソースオブジェクト
    [BoundThis]:bind関数の実行時に最初のパラメータとして渡されるオブジェクト
    [BoundArgs]:bind関数の実行時に2番目のパラメータから渡される配列

    の最後の部分


    今日はthisについて知りました.聞いてみたところ、これは単純な暗記に似ているという考えが生まれた.ここで呼び出されたthisは何を参照していますか.そこで呼び出されたthisは何を参照していますか.こんな感じで
    要するに、私の頭の中に抽象的な形で現れた概念が具体的に捉えられているのは良い感じです.今まで何をしたのか分からなかった.
    明日は待ちに待った実行コンテキストを知る番だ.以前、コンテキストの実行を理解しようとしたときに失敗しました.でも今の私は違う...完全に知ることができる.

    リファレンスサイト


    MDN Webドキュメント
    李雄模のWebプログラミングチュートリアル