「this」キーワードはどのように機能しますか?


1309

thisStack OverflowサイトのJavaScriptでキーワードがどのように正しく(そして正しく)使用されているかについての明確な説明がないようです。

私はそれに非常に奇妙な振る舞いを見ましたが、なぜそれが起こったのか理解できませんでした。

どのように機能しthis、いつ使用する必要がありますか?




2
Peter Michauxは、this peter.michaux.ca
Marcel Korpel

1
MDNの概要は、ハーフ悪いわけではない... developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/...
datの

2
thisキーワードの興味深い説明:rainsoft.io/gentle-explanation-of-this-in-javascript
Dmitri Pavlutin

回答:


1350

最初にMike Westの記事Scope in JavaScriptmirror)を読むことをお勧めします。これは、thisJavaScriptの概念とスコープチェーンの優れたわかりやすい紹介です。

に慣れればthis、ルールは実際にはかなり簡単です。ECMAScriptの5.1標準の定義this

§11.1.1thisキーワード

this現在の実行コンテキストのThisBindingの値に評価さキーワード

thisBindingは、オブジェクトへの参照を保持する特別なCPUレジスターのように、JavaScriptインタープリターがJavaScriptコードを評価するときに維持するものです。インタプリタは、次の3つの異なるケースのいずれかで実行コンテキストを確立するたびに、ThisBindingを更新します。

1.初期グローバル実行コンテキスト

これは、トップレベルで評価されるJavaScriptコードの場合です<script>

<script>
  alert("I'm evaluated in the initial global execution context!");

  setTimeout(function () {
      alert("I'm NOT evaluated in the initial global execution context.");
  }, 1);
</script>

初期グローバル実行コンテキストでコードを評価するとき、ThisBindingはグローバルオブジェクトに設定されますwindow§10.4.1.1)。

評価コードの入力

  • eval() ThisBinding への直接呼び出しによる変更はありません。これは、呼び出し実行コンテキストのThisBindingと同じ値です(§10.4.2(2)(a))。

  • eval()
    ThisBindingを直接呼び出さない場合、初期グローバル実行コンテキストで実行されているかのようにグローバルオブジェクトに設定されます(§10.4.2(1))。

§15.1.2.1.1は、直接呼び出しが何であるかを定義していeval()ます。基本的には、eval(...)のようなものに対し、直接呼び出しである(0, eval)(...)var indirectEval = eval; indirectEval(...);の間接的な呼び出しですeval()JavaScriptで(1、eval)( 'this')とeval( 'this')のチャックjの答えを参照してくださいそして、ドミトリーSoshnikovのECMA-262から5詳細に示します。第2章厳密モード。間接eval()呼び出しを使用する可能性がある場合。

機能コードの入力

これは、関数を呼び出すときに発生します。関数がin obj.myMethod()または同等のオブジェクトなどで呼び出されるとobj["myMethod"]()、ThisBindingがオブジェクトに設定されます(obj例では、§13.2.1)。他のほとんどの場合、ThisBindingはグローバルオブジェクトに設定されます(§10.4.3)。

「他のほとんどの場合」と記述する理由は、引数リストでThisBindingを指定できるECMAScript 5組み込み関数が8つあるためです。これらの特別な関数は、関数をthisArg呼び出すときにThisBindingになる、いわゆるを取ります(§10.4.3)。

これらの特別な組み込み関数は次のとおりです。

  • Function.prototype.apply( thisArg, argArray )
  • Function.prototype.call( thisArg [ , arg1 [ , arg2, ... ] ] )
  • Function.prototype.bind( thisArg [ , arg1 [ , arg2, ... ] ] )
  • Array.prototype.every( callbackfn [ , thisArg ] )
  • Array.prototype.some( callbackfn [ , thisArg ] )
  • Array.prototype.forEach( callbackfn [ , thisArg ] )
  • Array.prototype.map( callbackfn [ , thisArg ] )
  • Array.prototype.filter( callbackfn [ , thisArg ] )

Function.prototype関数の場合、関数オブジェクトで呼び出されますが、ThisBindingを関数オブジェクトに設定するのではなく、ThisBindingをに設定しますthisArg

Array.prototype関数の場合、与えられた場合、callbackfnThisBindingが設定されている実行コンテキストで指定されたものが呼び出さthisArgれます。それ以外の場合は、グローバルオブジェクト。

これらはプレーンJavaScriptのルールです。JavaScriptライブラリ(jQueryなど)の使用を開始すると、特定のライブラリ関数がの値を操作する場合がありthisます。これらのJavaScriptライブラリの開発者は、最も一般的な使用例をサポートする傾向があるため、これを行います。また、ライブラリのユーザーは通常、この動作がより便利であると感じています。thisライブラリ関数を参照するコールバック関数を渡すthisときは、関数が呼び出されたときの値が何であるかについて、ドキュメントを参照してください。

JavaScriptライブラリがの値をどのように操作するのか疑問に思っている場合this、ライブラリは、を受け入れる組み込みのJavaScript関数の1つを単に使用していますthisArg。あなたも、コールバック関数を使用して独自の関数を記述できますthisArg

function doWork(callbackfn, thisArg) {
    //...
    if (callbackfn != null) callbackfn.call(thisArg);
}

私がまだ言及しなかった特別なケースがあります。newオペレーターを介して新しいオブジェクトを構築する場合、JavaScriptインタープリターは新しい空のオブジェクトを作成し、いくつかの内部プロパティを設定してから、新しいオブジェクトでコンストラクター関数を呼び出します。したがって、コンストラクターコンテキストで関数が呼び出された場合、の値はthisインタープリターが作成した新しいオブジェクトです。

function MyType() {
    this.someData = "a string";
}

var instance = new MyType();
// Kind of like the following, but there are more steps involved:
// var instance = {};
// MyType.call(instance);

矢印関数

矢印関数(ECMA6で導入)はのスコープを変更しますthis。既存の標準的な質問、矢印関数vs関数宣言/式を参照してください:それらは同等/交換可能ですか?詳細については。しかし、要するに:

アロー関数には独自のthis....バインディングがありません。代わりに、これらの識別子は他の変数と同様に字句スコープで解決されます。つまり、アロー関数の内部では、アロー関数が定義されている環境のthis値を参照thisします。

楽しみのために、いくつかの例で理解をテストしてください

答えを明らかにするには、薄い灰色のボックスの上にマウスを置きます。

  1. thisマークされたラインでの値は何ですか?どうして?

    window —マークされた行は、初期グローバル実行コンテキストで評価されます。

    if (true) {
        // What is `this` here?
    }
  2. が実行されたthisときにマークされた行の値は何obj.staticFunction()ですか?どうして?

    obj —オブジェクトの関数を呼び出すと、ThisBindingがオブジェクトに設定されます。

    var obj = {
        someData: "a string"
    };
    
    function myFun() {
        return this // What is `this` here?
    }
    
    obj.staticFunction = myFun;
    
    console.log("this is window:", obj.staticFunction() == window);
    console.log("this is obj:", obj.staticFunction() == obj);
      

  3. thisマークされたラインでの値は何ですか?どうして?

    window

    この例では、JavaScriptインタープリターが関数コードに入りますが、オブジェクトでmyFun/ obj.myMethodが呼び出されないため、ThisBindingはに設定されwindowます。

    これは、メソッド(obj.myMethod)にアクセスしてバインドされたメソッドオブジェクトを作成するPythonとは異なります

    var obj = {
        myMethod: function () {
            return this; // What is `this` here?
        }
    };
    var myFun = obj.myMethod;
    console.log("this is window:", myFun() == window);
    console.log("this is obj:", myFun() == obj);
      

  4. thisマークされたラインでの値は何ですか?どうして?

    window

    これはトリッキーでした。評価コードを評価するとき、thisですobj。ただし、評価コードでmyFunは、オブジェクトwindowに対してが呼び出されないため、呼び出しに対してThisBindingがに設定されています。

    function myFun() {
        return this; // What is `this` here?
    }
    var obj = {
        myMethod: function () {
            eval("myFun()");
        }
    };
  5. thisマークされたラインでの値は何ですか?どうして?

    obj

    この行myFun.call(obj);は、最初の引数としてFunction.prototype.call()受け入れる特別な組み込み関数を呼び出していthisArgます。

    function myFun() {
        return this; // What is `this` here?
    }
    var obj = {
        someData: "a string"
    };
    console.log("this is window:", myFun.call(obj) == window);
    console.log("this is obj:", myFun.call(obj) == obj);
      


6
@Ali:ECMAScript標準のエディション5.1、ECMA-262内のセクションへの参照です。必要に応じて、技術的な詳細について規格を読むことができるように、それらを提供します。
Daniel Trebbien 2013

1
@supertonskyは#2について正しいと思います-myFun()がオブジェクトのメソッドとしてではなくグローバルスコープから呼び出された場合、「this」がグローバルオブジェクトになるため、質問のフレーズが重要になります。ところで、私マウスオーバーを使用してこのようなものの答えを得るためのアイデアが本当に好きです。
user655489 2013年

2
しかし、jsfiddle.net/H4LYm/2があることを示しsetTimeout例が持っているthisのをwindow(global)
ケビンメレディス

2
Pythonの1から来ると、私は第三例にぶつかったとき、私が持っていた欲求不満のレベルを想像.. SMH
マリウスMucenicu

1
この回答は、変更が単に用語である場合でも、ES2020の現実を反映するように更新する必要があります。
ベンアストン

156

this異なっJavaScriptでキーワード振る舞いは他の言語と比較します。オブジェクト指向言語では、thisキーワードはクラスの現在のインスタンスを指します。JavaScriptでは、の値はthis関数(context.function())の呼び出しコンテキストとそれが呼び出される場所によって決まります。

1.グローバルコンテキストで使用する場合

thisグローバルコンテキストで使用すると、(windowブラウザで)グローバルオブジェクトにバインドされます

document.write(this);  //[object Window]

thisグローバルコンテキストで定義された関数の内部で使用するとthis、関数は実際にはグローバルコンテキストのメソッドになるため、は引き続きグローバルオブジェクトにバインドされます。

function f1()
{
   return this;
}
document.write(f1());  //[object Window]

上記f1はグローバルオブジェクトのメソッドです。したがってwindow、次のようにオブジェクトで呼び出すこともできます。

function f()
{
    return this;
}

document.write(window.f()); //[object Window]

2.オブジェクトメソッド内で使用する場合

thisオブジェクトメソッド内でキーワードを使用するthisと、「即時」の囲みオブジェクトにバインドされます。

var obj = {
    name: "obj",
    f: function () {
        return this + ":" + this.name;
    }
};
document.write(obj.f());  //[object Object]:obj

上記では、即時という単語を二重引用符で囲んでいます。これは、オブジェクトを別のオブジェクト内にネストするthisと、直接の親にバインドされるということです。

var obj = {
    name: "obj1",
    nestedobj: {
        name:"nestedobj",
        f: function () {
            return this + ":" + this.name;
        }
    }            
}

document.write(obj.nestedobj.f()); //[object Object]:nestedobj

メソッドとしてオブジェクトに関数を明示的に追加した場合でも、上記のルールに従いthisます。つまり、直接の親オブジェクトを指します。

var obj1 = {
    name: "obj1",
}

function returnName() {
    return this + ":" + this.name;
}

obj1.f = returnName; //add method to object
document.write(obj1.f()); //[object Object]:obj1

3.コンテキストレス関数を呼び出すとき

thisコンテキストなしで(つまり、オブジェクト上ではなく)呼び出される関数内を使用すると、(windowブラウザ内で)グローバルオブジェクトにバインドされます(関数がオブジェクト内で定義されている場合でも)。

var context = "global";

var obj = {  
    context: "object",
    method: function () {                  
        function f() {
            var context = "function";
            return this + ":" +this.context; 
        };
        return f(); //invoked without context
    }
};

document.write(obj.method()); //[object Window]:global 

関数ですべてを試す

上記のポイントも関数で試すことができます。ただし、いくつかの違いがあります。

  • 上記では、オブジェクトリテラル表記を使用してオブジェクトにメンバーを追加しました。を使用して、関数にメンバーを追加できthisます。それらを指定します。
  • オブジェクトリテラル表記は、すぐに使用できるオブジェクトのインスタンスを作成します。関数では、最初にnew演算子を使用してインスタンスを作成する必要がある場合があります。
  • また、オブジェクトリテラルアプローチでは、ドット演算子を使用して、定義済みのオブジェクトにメンバーを明示的に追加できます。これは特定のインスタンスにのみ追加されます。ただし、関数のすべてのインスタンスに反映されるように、関数プロトタイプに変数を追加しました。

以下では、Object this以上で行ったことをすべて試しましたが、オブジェクトを直接作成する代わりに、まず関数を作成しました。

/********************************************************************* 
  1. When you add variable to the function using this keyword, it 
     gets added to the function prototype, thus allowing all function 
     instances to have their own copy of the variables added.
*********************************************************************/
function functionDef()
{
    this.name = "ObjDefinition";
    this.getName = function(){                
        return this+":"+this.name;
    }
}        

obj1 = new functionDef();
document.write(obj1.getName() + "<br />"); //[object Object]:ObjDefinition   

/********************************************************************* 
   2. Members explicitly added to the function protorype also behave 
      as above: all function instances have their own copy of the 
      variable added.
*********************************************************************/
functionDef.prototype.version = 1;
functionDef.prototype.getVersion = function(){
    return "v"+this.version; //see how this.version refers to the
                             //version variable added through 
                             //prototype
}
document.write(obj1.getVersion() + "<br />"); //v1

/********************************************************************* 
   3. Illustrating that the function variables added by both above 
      ways have their own copies across function instances
*********************************************************************/
functionDef.prototype.incrementVersion = function(){
    this.version = this.version + 1;
}
var obj2 = new functionDef();
document.write(obj2.getVersion() + "<br />"); //v1

obj2.incrementVersion();      //incrementing version in obj2
                              //does not affect obj1 version

document.write(obj2.getVersion() + "<br />"); //v2
document.write(obj1.getVersion() + "<br />"); //v1

/********************************************************************* 
   4. `this` keyword refers to the immediate parent object. If you 
       nest the object through function prototype, then `this` inside 
       object refers to the nested object not the function instance
*********************************************************************/
functionDef.prototype.nestedObj = { name: 'nestedObj', 
                                    getName1 : function(){
                                        return this+":"+this.name;
                                    }                            
                                  };

document.write(obj2.nestedObj.getName1() + "<br />"); //[object Object]:nestedObj

/********************************************************************* 
   5. If the method is on an object's prototype chain, `this` refers 
      to the object the method was called on, as if the method was on 
      the object.
*********************************************************************/
var ProtoObj = { fun: function () { return this.a } };
var obj3 = Object.create(ProtoObj); //creating an object setting ProtoObj
                                    //as its prototype
obj3.a = 999;                       //adding instance member to obj3
document.write(obj3.fun()+"<br />");//999
                                    //calling obj3.fun() makes 
                                    //ProtoObj.fun() to access obj3.a as 
                                    //if fun() is defined on obj3

4.コンストラクター関数内で使用する場合

関数がコンストラクターとして使用される場合(つまり、newキーワードで呼び出される場合)、this関数本体の内部は、構築される新しいオブジェクトを指します。

var myname = "global context";
function SimpleFun()
{
    this.myname = "simple function";
}

var obj1 = new SimpleFun(); //adds myname to obj1
//1. `new` causes `this` inside the SimpleFun() to point to the
//   object being constructed thus adding any member
//   created inside SimipleFun() using this.membername to the
//   object being constructed
//2. And by default `new` makes function to return newly 
//   constructed object if no explicit return value is specified

document.write(obj1.myname); //simple function

5.プロトタイプチェーンで定義された関数内で使用する場合

メソッドがオブジェクトのプロトタイプチェーンにある場合、thisそのようなメソッド内では、メソッドがオブジェクトで定義されているかのように、メソッドが呼び出されたオブジェクトを参照します。

var ProtoObj = {
    fun: function () {
        return this.a;
    }
};
//Object.create() creates object with ProtoObj as its
//prototype and assigns it to obj3, thus making fun() 
//to be the method on its prototype chain

var obj3 = Object.create(ProtoObj);
obj3.a = 999;
document.write(obj3.fun()); //999

//Notice that fun() is defined on obj3's prototype but 
//`this.a` inside fun() retrieves obj3.a   

6. call()、apply()およびbind()関数の内部

  • これらのメソッドはすべてで定義されていFunction.prototypeます。
  • これらのメソッドを使用すると、関数を1回記述して別のコンテキストで呼び出すことができます。つまり、this関数の実行中に使用される値を指定できます。また、呼び出されたときに元の関数に渡されるすべてのパラメーターを受け取ります。
  • fun.apply(obj1 [, argsArray])内部obj1の値として設定し、その引数として渡す要素を呼び出します。thisfun()fun()argsArray
  • fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])- 内部obj1の値として設定し、引数として渡す呼び出し。thisfun()fun()arg1, arg2, arg3, ...
  • fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])- 内部funがバインドされ、指定されたパラメーターにバインドされたパラメーターをfun持つ関数への参照を返します。thisobj1funarg1, arg2, arg3,...
  • 今ではapplycallとのbind違いが明らかになっているはずです。apply配列のようなオブジェクト、つまり数値lengthプロパティと対応する負でない整数プロパティを持つオブジェクトとして機能する引数を指定することができます。一方call、関数の引数を直接指定できます。両方とも、指定されたコンテキストで、指定された引数を使用して関数applycallすぐに呼び出します。一方、bind指定されたthis値と引数にバインドされた関数を返すだけです。この返された関数への参照を変数に割り当てることでキャプチャでき、後でいつでも呼び出すことができます。
function add(inc1, inc2)
{
    return this.a + inc1 + inc2;
}

var o = { a : 4 };
document.write(add.call(o, 5, 6)+"<br />"); //15
      //above add.call(o,5,6) sets `this` inside
      //add() to `o` and calls add() resulting:
      // this.a + inc1 + inc2 = 
      // `o.a` i.e. 4 + 5 + 6 = 15
document.write(add.apply(o, [5, 6]) + "<br />"); //15
      // `o.a` i.e. 4 + 5 + 6 = 15

var g = add.bind(o, 5, 6);       //g: `o.a` i.e. 4 + 5 + 6
document.write(g()+"<br />");    //15

var h = add.bind(o, 5);          //h: `o.a` i.e. 4 + 5 + ?
document.write(h(6) + "<br />"); //15
      // 4 + 5 + 6 = 15
document.write(h() + "<br />");  //NaN
      //no parameter is passed to h()
      //thus inc2 inside add() is `undefined`
      //4 + 5 + undefined = NaN</code>

7. this内部イベントハンドラー

  • 要素のイベントハンドラーに関数を直接割り当てる場合、thisイベント処理関数内で直接使用すると、対応する要素が参照されます。このような直接的な機能の割り当てはaddeventListener、メソッドを使用して、またはのような従来のイベント登録メソッドを介して実行できますonclick
  • 同様に、要素のthisイベントプロパティ(など<button onclick="...this..." >)内で直接使用する場合は、要素を参照します。
  • ただしthis、イベント処理関数またはイベントプロパティ内で呼び出された他の関数を介して間接的に使用すると、グローバルオブジェクトに解決されますwindow
  • 上記の同じ動作は、Microsoftのイベント登録モデルメソッドを使用して関数をイベントハンドラーにアタッチしたときにも実現されattachEventます。関数をイベントハンドラーに割り当てる(つまり、要素の関数メソッドを作成する)代わりに、イベントで関数を呼び出します(グローバルコンテキストで効果的に呼び出します)。

JSFiddleでこれを試すことをお勧めします。

<script> 
    function clickedMe() {
       alert(this + " : " + this.tagName + " : " + this.id);
    } 
    document.getElementById("button1").addEventListener("click", clickedMe, false);
    document.getElementById("button2").onclick = clickedMe;
    document.getElementById("button5").attachEvent('onclick', clickedMe);   
</script>

<h3>Using `this` "directly" inside event handler or event property</h3>
<button id="button1">click() "assigned" using addEventListner() </button><br />
<button id="button2">click() "assigned" using click() </button><br />
<button id="button3" onclick="alert(this+ ' : ' + this.tagName + ' : ' + this.id);">used `this` directly in click event property</button>

<h3>Using `this` "indirectly" inside event handler or event property</h3>
<button onclick="alert((function(){return this + ' : ' + this.tagName + ' : ' + this.id;})());">`this` used indirectly, inside function <br /> defined & called inside event property</button><br />

<button id="button4" onclick="clickedMe()">`this` used indirectly, inside function <br /> called inside event property</button> <br />

IE only: <button id="button5">click() "attached" using attachEvent() </button>

8. thisES6の矢印関数

アロー関数でthisは、一般的な変数のように動作します:字句スコープから継承されます。関数のthis矢印関数が定義され、矢印機能のだろうthis

したがって、これは次と同じ動作です。

(function(){}).bind(this)

次のコードを参照してください。

const globalArrowFunction = () => {
  return this;
};

console.log(globalArrowFunction()); //window

const contextObject = {
  method1: () => {return this},
  method2: function(){
    return () => {return this};
  }
};

console.log(contextObject.method1()); //window

const contextLessFunction = contextObject.method1;

console.log(contextLessFunction()); //window

console.log(contextObject.method2()()) //contextObject

const innerArrowFunction = contextObject.method2();

console.log(innerArrowFunction()); //contextObject 

「グローバルコンテキストで定義された関数内でこれを使用すると、関数は実際にはグローバルコンテキストのメソッドになるため、これは依然としてグローバルオブジェクトにバインドされます。」間違っている。これは、関数の呼び出し方法またはbindによって設定されます。定義された場所ではありません。ベース基準(「コンテキスト」)することなく、任意の関数を呼び出すと、デフォルトになり、これをグローバルオブジェクトまたは厳密モードで未定義のままです。
RobG 2014年

@RobG hmmかもしれませんが、MDNでこれを見つけました:この場合、の値はthis呼び出しによって設定されていません。コードはストリクトモードではないので、の値はthis常にオブジェクトでなければならず、デフォルトでグローバルオブジェクトになります。実際、私は直接callを実行できると思ったのはwindow.f1()そのためです。そのため、このメソッドf1()は既にwindowオブジェクトにアタッチされています。つまり、呼び出しの前です。私はそれを間違っていますか?
Mahesha999 2014年

私はあなたがこれの設定を「関数は実際にはグローバルコンテキストのメソッドになっている」とリンクしているようにコメントしていました(おそらく明確window.fnではありません)。関数が定義されている場所ではなく、呼び出しで基本参照が使用されなかったため、これはデフォルトでグローバルオブジェクトになります(したがって、これは関数の呼び出し方法によって設定されます)。を使用して明示的に呼び出す場合はwindow.fnこれwindowに設定します。同じ結果、それについての異なる方法。:-)
RobG 2014年

「上記で私は言葉をすぐに付けました...」いいえ、そうしませんでした。エラーを修正するように修正していただけますか?答えには意味があるように見えるので、何か間違ったことを学ぶのを恐れてエラーが修正されるまで読み続けることができません。
TylerH 2014

@TylerHブラウザーでこのページでCtrl + Fを実行して、文字列「即時」(二重引用符を含む)を検索します。
誤解して

64

JavaScriptの this

単純な関数呼び出し

次の関数について考えてみます。

function foo() {
    console.log("bar");
    console.log(this);
}
foo(); // calling the function

これは通常モードで実行されていることに注意してください。つまり、厳密モードは使用されません。

ブラウザで実行する場合、の値はthisとして記録されwindowます。これは、windowがWebブラウザーのスコープ内のグローバル変数であるためです。

node.jsなどの環境で同じコードを実行するとthis、アプリのグローバル変数を参照します。

ここ"use strict";で、関数宣言の先頭にステートメントを追加してこれをストリクトモードで実行するとthis、どちらの環境でもグローバル変数を参照しなくなります。これは、厳密モードでの混乱を避けるために行われます。thisこれはまさにlogですundefined。なぜなら、それが何であるか、それが定義されていないからです。

次の場合、の値を操作する方法を確認しますthis

オブジェクトの関数を呼び出す

これにはさまざまな方法があります。forEachandのようなJavascriptでネイティブメソッドを呼び出した場合、その場合slicethis変数はObjectその関数を呼び出したを参照していることをすでに知っているはずです(javascriptでは、sとs Objectを含むほぼすべてがであることに注意してください)。たとえば、次のコードを見てください。ArrayFunction

var myObj = {key: "Obj"};
myObj.logThis = function () {
    // I am a method
    console.log(this);
}
myObj.logThis(); // myObj is logged

Objectを保持するプロパティが含まれている場合Function、そのプロパティはメソッドと呼ばれます。このメソッドは、呼び出されると、関連付けられているthis変数に常に設定されObjectます。これは、厳密モードと非厳密モードの両方に当てはまります。

メソッドが別の変数に保存(またはコピー)されている場合、への参照thisは新しい変数に保持されなくなります。例えば:

// continuing with the previous code snippet

var myVar = myObj.logThis;
myVar();
// logs either of window/global/undefined based on mode of operation

より一般的な実用的なシナリオを検討します。

var el = document.getElementById('idOfEl');
el.addEventListener('click', function() { console.log(this) });
// the function called by addEventListener contains this as the reference to the element
// so clicking on our element would log that element itself

newキーワード

JavaScriptのコンストラクター関数について考えてみましょう。

function Person (name) {
    this.name = name;
    this.sayHello = function () {
        console.log ("Hello", this);
    }
}

var awal = new Person("Awal");
awal.sayHello();
// In `awal.sayHello`, `this` contains the reference to the variable `awal`

これはどのように作動しますか?さて、newキーワードを使用するとどうなるか見てみましょう。

  1. newキーワードを指定して関数を呼び出すと、Objectタイプのがすぐに初期化されますPerson
  2. このコンストラクタのコンストラクタはにObject設定されていPersonます。また、それだけtypeof awalが返されることに注意してくださいObject
  3. この新しいにObjectはのプロトタイプが割り当てられPerson.prototypeます。つまり、Personプロトタイプ内のメソッドまたはプロパティはPerson、を含むのすべてのインスタンスで使用できますawal
  4. 関数Person自体が呼び出されます。this新しく構築されたオブジェクトへの参照awalです。

かなり簡単です、え?

公式のECMAScript仕様には、そのようなタイプの関数は実際の関数であるとはどこにも記載されていないことに注意してくださいconstructor。これらは通常の関数でありnew、任意の関数で使用できます。私たちはそれらをそのように使用するだけなので、それらをそのようにのみ呼びます。

関数の関数の呼び出し:callおよびapply

つまり、functionsもObjects(そしてJavaScriptの実際のファーストクラス変数)なので、関数にもメソッドがあります。

すべての関数はglobalから継承され、Functionその多くのメソッドのうち2つはcalland applyであり、両方を使用して、thisそれらが呼び出される関数のの値を操作できます。

function foo () { console.log (this, arguments); }
var thisArg = {myObj: "is cool"};
foo.call(thisArg, 1, 2, 3);

これはの典型的な使用例ですcall。基本的に最初のパラメータを取り、this関数fooへの参照として設定しますthisArg。に渡される他のすべてのパラメーターは、引数としてcall関数に渡さfooれます。
したがって、上記のコードは{myObj: "is cool"}, [1, 2, 3]コンソールにログインします。this任意の関数のの値を変更するためのかなり良い方法。

applycall2つのパラメーターのみを受け取ることを受け入れるのとほぼ同じthisArgです。関数に渡される引数を含む配列です。したがって、上記のcall呼び出しは次のように変換できますapply

foo.apply(thisArg, [1,2,3])

そのノートcallapplyの値は上書きすることができthis、我々は第二弾で議論ドットメソッド呼び出しによってセット。十分に単純です:)

プレゼン.... bind

bind弟であるcallapply。これはFunction、Javascriptのグローバルコンストラクターからすべての関数によって継承されるメソッドでもあります。差bindおよびcall/ apply両方のことであるcallとすると、apply実際に関数を呼び出します。bind一方、thisArgおよびがarguments事前設定された新しい関数を返します。これをよりよく理解するために例を見てみましょう:

function foo (a, b) {
    console.log (this, arguments);
}
var thisArg = {myObj: "even more cool now"};
var bound = foo.bind(thisArg, 1, 2);
console.log (typeof bound); // logs `function`
console.log (bound);
/* logs `function () { native code }` */

bound(); // calling the function returned by `.bind`
// logs `{myObj: "even more cool now"}, [1, 2]`

3つの違いをご覧ください。微妙ですが、使い方は異なります。callおよびと同様にapply、ドットメソッドの呼び出しによって設定されbindた値もthisオーバーライドします。

また、これらの3つの関数はどちらも元の関数を変更しないことに注意してください。callそして、applyしながら、新鮮に構築関数から値を返すbindと呼ばれる準備ができて、新鮮に構築機能自体を返します。

余分なもの、これをコピー

場合thisによっては、スコープ、特にネストされたスコープによって変化することが気に入らないことがあります。次の例を見てください。

var myObj = {
    hello: function () {
        return "world"
        },
    myMethod: function () {
        // copy this, variable names are case-sensitive
        var that = this;
        // callbacks ftw \o/
        foo.bar("args", function () {
            // I want to call `hello` here
            this.hello(); // error
            // but `this` references to `foo` damn!
            // oh wait we have a backup \o/
            that.hello(); // "world"
        });
    }
  };

上記のコードではthis、ネストされたスコープで値が変更されたことがわかりますがthis、元のスコープからの値が必要でした。そのため、の代わりににコピーthisthatて使用しましたthis。賢い、え?

インデックス:

  1. thisデフォルトでは何が保持されていますか?
  2. 関数をObject-dot表記のメソッドとして呼び出すとどうなりますか?
  3. newキーワードを使用するとどうなりますか?
  4. andでどのように操作thisしますか?callapply
  5. を使用しbindます。
  6. thisネストされたスコープの問題を解決するためのコピー。

47

「これ」はすべてスコープに関するものです。すべての関数には独自のスコープがあり、JSのすべてがオブジェクトであるため、関数でも「this」を使用していくつかの値をそれ自体に格納できます。OOP 101は、「this」はオブジェクトのインスタンスにのみ適用できることを教えています。したがって、関数が実行されるたびに、その関数の新しい「インスタンス」は「this」の新しい意味を持ちます。

ほとんどの人は、次のような匿名のクロージャー関数内で「this」を使用しようとすると混乱します。

(関数(値){
    this.value = value;
    $( '。some-elements')。each(function(elt){
        elt.innerHTML = this.value; // ええとああ!!おそらく未定義
    });
})(2);

したがって、ここでは、each()内で、「this」は期待する「値」を保持しません(から

this.value = value;
その上)。したがって、この(しゃれた意図はない)問題を解決するために、開発者は次のことができます。

(関数(値){
    var self = this; //小さな変更
    self.value = value;
    $( '。some-elements')。each(function(elt){
        elt.innerHTML = self.value; //ふw !! == 2
    });
})(2);

やってみて; あなたはこのプログラミングのパターンが好きになるでしょう


6
「JSのすべてがオブジェクトです」というのは正しくありません。JavaScriptに
Marcel Korpelの

6
プリミティブ値には、String#substring()、Number#toString()などのいくつかのメソッドが含まれているようです。そのため、その記事と同じ命名法ではなく、実際にはオブジェクトであるかのように動作します(すべてのプロトタイプ、つまりString#substring()は実際には次のとおりです:String.prototype.substring = function(){...})。私が間違っていたら訂正してください。
arunjitsingh 2010

12
thisキーワードは、スコープとは何の関係もありません。また、オブジェクトのプロパティではない関数にも意味があります。
Bergi

1
@ arunjitsingh—そのことについては2つの考え方があります。私は「すべてがオブジェクトですが、一部はプリミティブで表現できるので便利です」と言っているものが好きです。;-)
RobG、2015年

9
thisスコープについてすべてではありません。スコープと同じではない実行コンテキストがすべてです。JavaScriptはレキシカルにスコープされます(つまり、スコープはコードの場所によって決定されます)が、JavaScript thisを含む関数が呼び出される方法によって決定されます-関数の場所ではありません。
Scott Marcus

16

このスレッドが増えたので、thisトピックに新しい読者のためにいくつかのポイントをまとめました。

の値はどのようにthis決定されますか?

これは、英語などの自然言語で代名詞を使用するのと同じように使用します。「ジョンは電車に乗ろうとしているので速く走っています。」代わりに、「… ジョンは電車に乗ろうとしている」と書くこともできました。

var person = {    
    firstName: "Penelope",
    lastName: "Barrymore",
    fullName: function () {

    // We use "this" just as in the sentence above:
       console.log(this.firstName + " " + this.lastName);

    // We could have also written:
       console.log(person.firstName + " " + person.lastName);
    }
}

this オブジェクトが定義されている関数をオブジェクトが呼び出すまで、値は割り当てられません。グローバルスコープでは、すべてのグローバル変数と関数がwindowオブジェクトで定義されます。したがって、thisグローバル関数では、グローバルwindowオブジェクトを参照し、その値を持っています。

場合はuse strictthisグローバルで、任意のオブジェクトにバインドされていない無名関数には、の値を保持しますundefined

thisキーワードは、最も誤解我々が使用する方法借りる)1:場合this、2)我々が使用する方法割り当てるthis変数に、3)を使用するが、その関数thisコールバック関数として渡され、及び4)thisクロージャ内で使用されます-内部関数。(2)

テーブル

未来を保持するもの

ECMAスクリプト6で定義されている矢印関数はthis、囲んでいる(関数またはグローバル)スコープからのバインディングを採用します。

function foo() {
     // return an arrow function
     return (a) => {
     // `this` here is lexically inherited from `foo()`
     console.log(this.a);
  };
}
var obj1 = { a: 2 };
var obj2 = { a: 3 };

var bar = foo.call(obj1);
bar.call( obj2 ); // 2, not 3!

矢印関数はを使用する代わりに使用できますが、より広く理解されている語彙スコープを優先bind()して、従来のthisメカニズムを本質的に無効にしていることに注意することが重要です。(1)


参照:

  1. this&Object Prototypes、Kyle Simpson作。©2014 Getify Solutions。
  2. javascriptissexy.com- http://goo.gl/pvl0GX
  3. アンガスクロール-http: //goo.gl/Z2RacU

16

thisJavaScriptでは常に、実行中の関数の「所有者」を指します。

明示的な所有者が定義されていない場合、最上位の所有者であるウィンドウオブジェクトが参照されます。

だから私がしたなら

function someKindOfFunction() {
   this.style = 'foo';
}

element.onclick = someKindOfFunction;

this要素オブジェクトを参照します。しかし、注意してください。多くの人がこの間違いを犯します。

<element onclick="someKindOfFunction()">

後者の場合、関数を参照するだけで、要素に渡しません。したがって、thisウィンドウオブジェクトを参照します。


15

JavaScriptのすべての実行コンテキストには、次のように設定されるthisパラメータがあります。

  1. 関数の呼び出し方法(オブジェクトメソッドとしての呼び出しcallおよびapplyの使用、newの使用を含む)
  2. バインドの使用
  3. 字句的にアロー関数用(これは外部実行コンテキストのthisを採用)
  4. コードが厳密モードか非厳密モードか
  5. コードを使用して呼び出されたかどうか eval

この値はfunc.callfunc.applyまたはを使用して設定できfunc.bindます。

デフォルトでは、ほとんどの初心者を混乱させるものですが、DOM要素でイベントが発生した後にリスナーが呼び出されると、関数のこの値がDOM要素になります。

jQueryは、jQuery.proxyでこれを変更することを簡単にします。


9
すべての関数呼び出しにスコープがあると言うのは少し正しいです。つまり、thisJavaScriptで混乱しているの、それが関数自体の固有のプロパティではなく、関数の呼び出し方法のアーティファクトであるということです。
ポインティ

@先に感謝します。jsでこれについて最も混乱を引き起こすのは、以前に使用されたすべての言語(c#、c ++)で操作できないという事実です。nは常にオブジェクトインスタンスを指しますが、jsでは依存し、呼び出し時に変更できます。使用した機能func.callfunc.bind等-スシル
スシル

2
this関数のスコープを参照しませthis特定のオブジェクト(またはundefined)を参照します。これは、前述のとおり、.call()またはを使用して変更できます.apply()。関数のスコープは、(基本的には簡略化された場合)どの変数にアクセスできるかであり、これは完全に関数が宣言され、変更できない場所に依存します。
nnnnnn 2015年

@Pointy:「すべての関数呼び出しにスコープがあると言ったほうが正しいです。」関数(および現在はブロック)にはスコープがあり、関数呼び出しにコンテキストあります。スコープは、そのスコープ内のコードで使用できる識別子を定義します。コンテキストは、それらの識別子がバインドされる対象を定義します。
TJクラウダー2015年

1
「そのスコープが何であれ、「this」によって参照されます。」いいえ、thisおよびスコープは、ES5以前(たとえば、この回答が書かれたとき)で互いに何の関係もありません。(ES6別名)ES2015、内thisおよび範囲関連する1つの関数(矢印WRTかなり最小方法this矢印関数におけるその囲み範囲から継承される)が、this範囲を意味することはありません。
TJクラウダー2015年

10

ここでの一つの良い源であるthisではJavaScript

ここに要約があります:

  • グローバルこれ

    ブラウザでは、グローバルスコープで、thisあるwindowオブジェクト

    <script type="text/javascript">
      console.log(this === window); // true
      var foo = "bar";
      console.log(this.foo); // "bar"
      console.log(window.foo); // "bar"

    nodeREPLを使用して、thisトップの名前空間です。として参照できますglobal

    >this
      { ArrayBuffer: [Function: ArrayBuffer],
        Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
        Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
        ...
    >global === this
     true

    nodeスクリプトからの実行thisグローバルスコープに空のオブジェクトとして開始します。それは同じではありませんglobal

    \\test.js
    console.log(this);  \\ {}
    console.log(this === global); \\ fasle
  • これを機能させる

DOMイベントハンドラーの場合、またはa thisArgが提供されている場合(下を参照)を除き、ノードとブラウザーの両方で、グローバルスコープthisnew参照して呼び出されない関数で使用しています…

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    testThis();
    console.log(this.foo); //logs "foo"
</script>

を使用するuse strict;場合、その場合thisundefined

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      "use strict";
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    testThis();  //Uncaught TypeError: Cannot set property 'foo' of undefined 
</script>

あなたが持つ関数を呼び出す場合は、新しいコンテキストになりますが、それはグローバルを参照しません。newthisthis

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    new testThis();
    console.log(this.foo); //logs "bar"

    console.log(new testThis().foo); //logs "foo"
</script>
  • これのプロトタイプ

作成した関数は関数オブジェクトになります。それらは自動的に特別なprototypeプロパティを取得します。これは値を割り当てることができるものです。関数を呼び出してインスタンスを作成するnewと、prototypeプロパティに割り当てた値にアクセスできます。これらの値にはを使用してアクセスしますthis

function Thing() {
  console.log(this.foo);
}

Thing.prototype.foo = "bar";

var thing = new Thing(); //logs "bar"
console.log(thing.foo);  //logs "bar"

これは通常、割り当てに間違いである配列またはオブジェクトprototype。インスタンスごとに独自の配列が必要な場合は、プロトタイプではなく、関数でインスタンスを作成します。

function Thing() {
    this.things = [];
}

var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing1.things); //logs ["foo"]
console.log(thing2.things); //logs []
  • これに反対

thisオブジェクトの任意の関数で使用して、そのオブジェクトの他のプロパティを参照できます。これは、で作成したインスタンスとは異なりますnew

var obj = {
    foo: "bar",
    logFoo: function () {
        console.log(this.foo);
    }
};

obj.logFoo(); //logs "bar"
  • DOMイベントこれ

HTML DOMイベントハンドラーでthisは、常に、イベントがアタッチされたDOM要素への参照です

function Listener() {
    document.getElementById("foo").addEventListener("click",
       this.handleClick);
}
Listener.prototype.handleClick = function (event) {
    console.log(this); //logs "<div id="foo"></div>"
}

var listener = new Listener();
document.getElementById("foo").click();

あなたbindがコンテキストでない限り

function Listener() {
    document.getElementById("foo").addEventListener("click", 
        this.handleClick.bind(this));
}
Listener.prototype.handleClick = function (event) {
    console.log(this); //logs Listener {handleClick: function}
}

var listener = new Listener();
document.getElementById("foo").click();
  • HTMLこれ

JavaScriptを配置できるHTML属性内にthisは、要素への参照があります。

<div id="foo" onclick="console.log(this);"></div>
<script type="text/javascript">
document.getElementById("foo").click(); //logs <div id="foo"...
</script>
  • これを評価

を使用evalしてにアクセスできますthis

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    eval("console.log(this.foo)"); //logs "bar"
}

var thing = new Thing();
thing.logFoo();
  • これとともに

を使用withthisて、現在のスコープに追加し、明示的にthis参照せずに値を読み書きできますthis

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    with (this) {
        console.log(foo);
        foo = "foo";
    }
}

var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"
  • jQuery this

jQueryは多くの場所でthisDOM要素を参照します。

<div class="foo bar1"></div>
<div class="foo bar2"></div>
<script type="text/javascript">
$(".foo").each(function () {
    console.log(this); //logs <div class="foo...
});
$(".foo").on("click", function () {
    console.log(this); //logs <div class="foo...
});
$(".foo").each(function () {
    this.click();
});
</script>

9

ダニエル、素晴らしい説明!これに関するいくつかの単語と良いリストthisイベントハンドラーの場合の実行コンテキストポインターの。

つまり、 this JavaScriptでは、現在の関数の実行元(または実行コンテキスト)のオブジェクトを指し、常に読み取り専用であり、それを設定することはできません(そのような試みは、「無効な左手側の割り当て」メッセージ。

イベントハンドラーの場合:などのインラインイベントハンドラーは、<element onclick="foo">以前にアタッチされた他のすべてのハンドラーをオーバーライドするため、注意してください。インラインイベントの委任は避けてください。そして、反対論争を通じてこの例のリストに私をインスピレーションを与えてくれたZara Alaverdyanに感謝します:)

  • el.onclick = foo; // in the foo - obj
  • el.onclick = function () {this.style.color = '#fff';} // obj
  • el.onclick = function() {doSomething();} // In the doSomething - Window
  • el.addEventListener('click',foo,false) // in the foo - obj
  • el.attachEvent('onclick, function () { // this }') // window, all the compliance to IE :)
  • <button onclick="this.style.color = '#fff';"> // obj
  • <button onclick="foo"> // In the foo - window, but you can <button onclick="foo(this)">

9

JavaScriptで「this」キーワードがどのように解釈されるかについては、多くの混乱があります。うまくいけば、この記事ですべての人が一休みできるようになるでしょう。そしてもっとたくさん。記事全体を注意深くお読みください。この記事は長いので注意してください。

それが使用されるコンテキストに関係なく、「this」は常にJavascriptの「現在のオブジェクト」を参照します。ただし、「現在のオブジェクト」とは、コンテキストによって異なりますコンテキストが正確であってもよい1ないし6の

  1. グローバル(つまり、すべての機能の外側)
  2. 内部の「非バインド関数」呼び出し(つまり、functionName.bindの呼び出しによってバインドされていない関数
  3. functionName.callおよびfunctionName.applyを介した間接的な「非バインド関数」呼び出し
  4. 「バインドされた関数」呼び出しの内部(つまり、functionName.bindを呼び出すことによってバインドされた関数
  5. 「新規」によるオブジェクト作成中
  6. インラインDOMイベントハンドラー内

以下では、このコンテキストのそれぞれについて1つずつ説明します。

  1. グローバルコンテキスト(つまり、すべての関数の外):

    すべての関数の外側(つまり、グローバルコンテキスト)では、「現在のオブジェクト」(したがって「this」の値)は常に ブラウザーの「ウィンドウ」オブジェクトです。

  2. 内部の「非バインド関数」呼び出し

    直接「非バインド関数」呼び出し内では、関数呼び出しを呼び出したオブジェクトが「現在のオブジェクト」になります(したがって、「this」の値になります)。機能が明示せずに呼び出された場合、現在のオブジェクト現在のオブジェクトは、のいずれかである「窓」(非厳密モード)オブジェクト又は不定(厳密モード)。グローバルコンテキストで定義された関数(または変数)は 自動的に「ウィンドウ」オブジェクトのプロパティになります。たとえば、Suppose関数はグローバルコンテキストで次のように定義されます。

    function UserDefinedFunction(){
        alert(this)
        }

    次のように定義したかのように、ウィンドウオブジェクトのプロパティになります。

    window.UserDefinedFunction=function(){
      alert(this)
    }  

    「非厳密モード」では、直接介してこの関数を呼び出す/呼び出し 「()UserDefinedFunction」自動的としてたinvoke /呼ぶ「window.UserDefinedFunction()」製造「ウィンドウ」として 「現在のオブジェクト」の(従って、値を" this))内の UserDefinedFunction 。この関数を「非厳密モード」で呼び出すと、次のようになります。

    UserDefinedFunction() // displays [object Window]  as it automatically gets invoked as window.UserDefinedFunction()

    直接機能の起動/呼び出し「厳密モード」における 「)UserDefinedFunction(」「NOT」自動的としてたinvoke /呼び出し「window.UserDefinedFunction()」 .Hence 「現在のオブジェクト」(及びの値「この」「UserDefinedFunction」内 は未定義です。この機能を「厳密モード」で呼び出すと、次のようになります。

    UserDefinedFunction() // displays undefined

    ただし、ウィンドウオブジェクトを使用して明示的に呼び出すと、次のようになります。

    window.UserDefinedFunction() // "always displays [object Window]   irrespective of mode."

    別の例を見てみましょう。次のコードを見てください

     function UserDefinedFunction()
        {
            alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
        }
    
    var o1={
                a:1,
                b:2,
                f:UserDefinedFunction
          }
    var o2={
                c:3,
                d:4,
                f:UserDefinedFunction
           }
    
    o1.f() // Shall display 1,2,undefined,undefined
    o2.f() // Shall display undefined,undefined,3,4

    上記の例では、「UserDefinedFunction」o1を介して呼び出された場合、「this」o1の値を取り、そのプロパティ「a」「b」の値が表示されることがわかります。「c」「d」の値は、o1がこれらのプロパティを定義しないため、未定義として表示されました

    場合同様に「UserDefinedFunctionは」を通して呼び出されたO2「この」の値をとりO2とそのプロパティの値「C」「D」とのdisplayed.The値取得「」「B」のように示された未定義としてO2はありませんこれらのプロパティを定義しないでください。

  3. functionName.callおよびfunctionName.applyを介した間接的な「非バインド関数」呼び出し

    場合「非バウンド関数が」を通して呼ばれる functionName.call又はfunctionName.apply「現在のオブジェクト」(およびそれゆえ値「本」)の値に設定されている 「この」に渡されたパラメータ(最初のパラメータ)コール/ apply。次のコードは同じことを示しています。

    function UserDefinedFunction()
    {
        alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
    }
    var o1={
                a:1,
                b:2,
                f:UserDefinedFunction
           }
    var o2={
                c:3,
                d:4,
                f:UserDefinedFunction
           }
    
    UserDefinedFunction.call(o1) // Shall display 1,2,undefined,undefined
    UserDefinedFunction.apply(o1) // Shall display 1,2,undefined,undefined
    
    UserDefinedFunction.call(o2) // Shall display undefined,undefined,3,4
    UserDefinedFunction.apply(o2) // Shall display undefined,undefined,3,4
    
    o1.f.call(o2) // Shall display undefined,undefined,3,4
    o1.f.apply(o2) // Shall display undefined,undefined,3,4
    
    o2.f.call(o1) // Shall display 1,2,undefined,undefined
    o2.f.apply(o1) // Shall display 1,2,undefined,undefined

    上記のコードは、「非バインド関数」の「this」値がcall / applyを介して変更できることを明確に示しています。また、 「this」パラメーターが明示的にcall / applyに渡されない場合「現在のオブジェクト」(したがって「this」の値)は非厳密モードでは「ウィンドウ」に、厳密モードでは「未定義」に設定されます。

  4. 「バインドされた関数」呼び出しの内部(つまり、functionName.bindを呼び出すことによってバインドされた関数):

    バインドされた関数は、「this」値が修正された関数です。次のコードは、バインドされた関数の場合に「this」がどのように機能するかを示しています

    function UserDefinedFunction()
    {
        alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
    }
    var o1={
              a:1,
              b:2,
              f:UserDefinedFunction,
              bf:null
           }
    var o2={
               c:3,
               d:4,
               f:UserDefinedFunction,
               bf:null
            }
    
    var bound1=UserDefinedFunction.bind(o1); // permanantly fixes "this" value of function "bound1" to Object o1
    bound1() // Shall display 1,2,undefined,undefined
    
    var bound2=UserDefinedFunction.bind(o2); // permanantly fixes "this" value of function "bound2" to Object o2
    bound2() // Shall display undefined,undefined,3,4
    
    var bound3=o1.f.bind(o2); // permanantly fixes "this" value of function "bound3" to Object o2
    bound3() // Shall display undefined,undefined,3,4
    
    var bound4=o2.f.bind(o1); // permanantly fixes "this" value of function "bound4" to Object o1
    bound4() // Shall display 1,2,undefined,undefined
    
    o1.bf=UserDefinedFunction.bind(o2) // permanantly fixes "this" value of function "o1.bf" to Object o2
    o1.bf() // Shall display undefined,undefined,3,4
    
    o2.bf=UserDefinedFunction.bind(o1) // permanantly fixes "this" value of function "o2.bf" to Object o1
    o2.bf() // Shall display 1,2,undefined,undefined
    
    bound1.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
    
    bound1.apply(o2) // Shall still display 1,2,undefined,undefined. "apply" cannot alter the value of "this" for bound function
    
    o2.bf.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
    o2.bf.apply(o2) // Shall still display 1,2,undefined,undefined."apply" cannot alter the value of "this" for bound function

    上記のコードにあるように、「バインドされた関数」の「this」値は、call / applyを介して変更できません。また、「this」 パラメーターが明示的にバインドに渡されない場合、「現在のオブジェクト」 (したがって「this」の値)は、非厳密モードでは「ウィンドウ」に、厳密モードでは「未定義」に設定されます。もう一つ。すでにバインドされている関数をバインドしても、「this」の値は変更されません。最初のバインド機能によって設定された値として設定されたままになります。

  5. 「新規」によるオブジェクトの作成中

    コンストラクター関数内では、「現在のオブジェクト」(したがって「this」の値 )は、関数のバインドステータスに関係なく、「new」を通じて現在作成されているオブジェクトを参照します。ただし、コンストラクターがバインドされた関数の場合は、バインドされた関数に設定された定義済みの引数セットを使用して呼び出されます。

  6. インラインDOMイベントハンドラー内

    次のHTMLスニペットをご覧ください

    <button onclick='this.style.color=white'>Hello World</button>
    <div style='width:100px;height:100px;' onclick='OnDivClick(event,this)'>Hello World</div>

    「この」上記の例は、「button」要素と「div」要素をそれぞれ参照しています。

    最初の例では、ボタンをクリックすると、フォントの色が白に設定されます。

    2番目の例では、「div」要素がクリックされると、クリックされたdiv要素を参照する2番目のパラメーターを使用してOnDivClick関数を呼び出します。ただし、 OnDivClick内の「this」の値は、クリックされたdiv 要素を参照してはなりません。これは、非厳密モード厳密モードでそれぞれ「ウィンドウオブジェクト」または「未定義」として設定されるか (OnDivClick非バインド関数の場合)、または事前定義されたBound値に設定されます(OnDivClickバインド関数の場合

以下は記事全体の要約です

  1. グローバルコンテキストでは、「this」は常に「window」オブジェクトを指します

  2. 関数が呼び出されるときは常に、オブジェクト(「現在のオブジェクト」)のコンテキストで呼び出されます。場合は、現在のオブジェクトを明示的に提供されていない、現在のオブジェクトが あり、「ウィンドウオブジェクト」NON厳格なモード「未定義」デフォルトでstrictモードで。

  3. 非バインド関数内の「this」の値は、関数が呼び出されたコンテキスト内のオブジェクト「現在のオブジェクト」)への参照です

  4. 非バインド関数内の「this」の値は、関数の呼び出しメソッドと適用メソッドによってオーバーライドできます 。

  5. 「this」の値はBound関数に対して固定されており、関数のcallおよびapplyメソッドによってオーバーライドすることはできません。

  6. バインドおよび既にバインドされている関数は、「this」の値を変更しません。最初のバインド機能によって設定された値として設定されたままになります。

  7. コンストラクター内の「this」の値は、作成および初期化されるオブジェクトです

  8. インラインDOMイベントハンドラー内の「this」の値は、イベントハンドラーが指定されている要素への参照です。


9

おそらく最も詳細で包括的な記事thisは次のとおりです。

JavaScriptの「this」キーワードの穏やかな説明

背後にthisある考え方は、関数呼び出しタイプがthis値の設定に非常に重要であることを理解することです。


の特定thisに問題がある場合は、次のことを自問しないでください。

どこthisから取られますか?

しかし自問してみてください:

関数どのように呼び出されますか?

アロー関数(コンテキスト透過性の特殊なケース)については、次の点を確認してください。

thisアロー関数が定義されている場所にはどのような値がありますか?

この考え方は、対処するときに正しくthis、頭痛からあなたを救います。


あなたのブログへのリンクに加えて、あなたはそれらの質問をすることが誰かがthisキーワードを理解するのにどのように役立つかについて少し深く掘り下げることができますか?
Magnus Lind Oxlund

7

これは私が見た中で最高の説明です:JavaScriptを理解するこれをClarityで理解する

この基準電圧は常に指す(との値を保持する)、オブジェクト特異オブジェクトとそれがグローバルスコープ内の関数の外部で使用することができるが、それは通常、関数またはメソッド内で使用されています。strictモードを使用する場合、これは、グローバル関数およびオブジェクトにバインドされていない無名関数のundefinedの値を保持することに注意してください。

4つのシナリオがあり、これが混乱することができますが。

  1. メソッドを渡すとき(これを使用するコールバック関数として使用される引数として)。
  2. 内部関数(クロージャー)を使用する場合。this変数は関数自体からのみアクセス可能であり、内部関数からはアクセスできないため、クロージャーはthisキーワードを使用して外部関数のthis変数にアクセスできないことに注意してください。
  3. 場合に依拠する方法これは、場合コンテキスト全体変数に割り当てられ、この参照本来意図したよりも別のオブジェクトを。
  4. 使用している場合、これをバインドとともに、適用、および呼び出し方法。

彼はコード例、説明、解決策を提供してくれました。


6

疑似古典的な用語では、多くの講義が「this」キーワードを教える方法は、クラスまたはオブジェクトコンストラクターによってインスタンス化されるオブジェクトとしてです。クラスから新しいオブジェクトが構築されるたびに、内部で「this」オブジェクトのローカルインスタンスが作成されて返されることを想像してください。私はそれがこのように教えられたことを覚えています:

function Car(make, model, year) {
var this = {}; // under the hood, so to speak
this.make = make;
this.model = model;
this.year = year;
return this; // under the hood
}

var mycar = new Car('Eagle', 'Talon TSi', 1993);
// ========= under the hood
var this = {};
this.make = 'Eagle';
this.model = 'Talon TSi';
this.year = 1993;
return this;

5

thisJavaScriptは、場所によって動作がほとんど異なるため、JavaScriptで誤解されている概念の1つです。単に、現在実行している関数の「所有者」をthis指します。

this現在使用しているオブジェクト(別名実行コンテキスト)を取得するのに役立ちます。あなたは、現在の関数をどのオブジェクトに理解していれば実行なっている、あなたは簡単に現在のかを理解することができますthisです

var val = "window.val"

var obj = {
    val: "obj.val",
    innerMethod: function () {
        var val = "obj.val.inner",
            func = function () {
                var self = this;
                return self.val;
            };

        return func;
    },
    outerMethod: function(){
        return this.val;
    }
};

//This actually gets executed inside window object 
console.log(obj.innerMethod()()); //returns window.val

//Breakdown in to 2 lines explains this in detail
var _inn = obj.innerMethod();
console.log(_inn()); //returns window.val

console.log(obj.outerMethod()); //returns obj.val

上記では、同じ名前「val」の3つの変数を作成します。1つはグローバルコンテキストで、もう1つはobj内にあり、もう1つはobjのinnerMethod内にあります。JavaScriptは、ローカルからグローバルにスコープチェーンを上に移動することにより、特定のコンテキスト内の識別子を解決します。


this差別化できる場所はほとんどありません

オブジェクトのメソッドを呼び出す

var status = 1;
var helper = {
    status : 2,
    getStatus: function () {
        return this.status;
    }
};

var theStatus1 = helper.getStatus(); //line1
console.log(theStatus1); //2

var theStatus2 = helper.getStatus;
console.log(theStatus2()); //1

line1が実行されると、JavaScriptは関数呼び出しの実行コンテキスト(EC)を確立し、最後の「。」の前に来たものが参照するオブジェクトに設定thisます。。したがって、最後の行a()では、それがグローバルコンテキストで実行されたことを理解できますwindow

コンストラクター付き

this 作成中のオブジェクトを参照するために使用できます

function Person(name){
    this.personName = name;
    this.sayHello = function(){
        return "Hello " + this.personName;
    }
}

var person1 = new Person('Scott');
console.log(person1.sayHello()); //Hello Scott

var person2 = new Person('Hugh');
var sayHelloP2 = person2.sayHello;
console.log(sayHelloP2()); //Hello undefined

new Person()が実行されると、完全に新しいオブジェクトが作成されます。Personが呼び出され、そのthis新しいオブジェクトを参照するように設定されます。

関数呼び出し

function testFunc() {
    this.name = "Name";
    this.myCustomAttribute = "Custom Attribute";
    return this;
}

var whatIsThis = testFunc();
console.log(whatIsThis); //window

var whatIsThis2 = new testFunc();
console.log(whatIsThis2);  //testFunc() / object

console.log(window.myCustomAttribute); //Custom Attribute 

newキーワードを見逃した場合、whatIsThis見つけることができる最もグローバルなコンテキストを参照します(window

イベントハンドラー付き

イベントハンドラーがインラインの場合、thisグローバルオブジェクトを参照します

<script type="application/javascript">
    function click_handler() {
        alert(this); // alerts the window object
    }
</script>

<button id='thebutton' onclick='click_handler()'>Click me!</button>

JavaScriptを介してイベントハンドラーを追加する場合this、イベントを生成したDOM要素を参照します。



5

「this」の値は、関数が実行される「コンテキスト」に依存します。コンテキストは、任意のオブジェクトまたはグローバルオブジェクト、つまりウィンドウにすることができます。

したがって、「this」のセマンティックは、従来のOOP言語とは異なります。そしてそれは問題を引き起こします:1.関数が別の変数に渡されるとき(おそらくコールバック)。2.クロージャがクラスのメンバーメソッドから呼び出されたとき。

どちらの場合も、これはウィンドウに設定されます。


3

Whould このヘルプ?(JavaScriptの 'this'のほとんどの混乱は、それが通常はオブジェクトにリンクされていないが、現在の実行スコープにリンクされているという事実から来ています-それは正確に機能するわけではないかもしれませんが、常に私にはそのように感じられます-完全な説明については記事を参照してください)


1
現在の実行コンテキストにリンクされている」と言ったほうがいいでしょう。ES6(ドラフト)を除き、これは矢印関数で変更されます。これは、外部実行コンテキストで解決されます。
RobG、2015年

3

これについて少し情報キーワード

thisコードなしで、グローバルスコープのコンソールにキーワードを記録しましょう。

console.log(this)

では、クライアント/ブラウザの thisキーワードはグローバルオブジェクトでありますwindow

console.log(this === window) // true

そして

ではサーバー/ノード/ Javascriptの実行時 thisのキーワードもあるグローバルオブジェクトでありますmodule.exports

console.log(this === module.exports) // true
console.log(this === exports) // true

覚えておいてくださいexportsへの参照だけですmodule.exports


1

このようなスコープの使用法

  <script type="text/javascript" language="javascript">
$('#tbleName tbody tr').each(function{
var txt='';
txt += $(this).find("td").eq(0).text();
\\same as above but synatx different
var txt1='';
 txt1+=$('#tbleName tbody tr').eq(0).text();
alert(txt1)
});
</script>

上記の例ではtxt1とtxtの値は同じです$(this)= $( '#tbleName tbody tr')は同じです


1

私は別の考えを持っています this他の回答とは見方をしていますが、役に立てれば幸いです。

JavaScriptを確認する1つの方法は、関数を呼び出す方法が1つしかないことを確認することです1。です

functionObject.call(objectForThis, arg0, arg1, arg2, ...);

には常にいくつかの値が提供されobjectForThisます。

他のすべてはのための構文糖です functionObject.call

したがって、他のすべては、それがにどのように変換されるかによって説明できますfunctionObject.call

関数を呼び出すだけの場合this、「グローバルオブジェクト」であり、これはブラウザではウィンドウです。

function foo() {
  console.log(this);
}

foo();  // this is the window object

言い換えると、

foo();

に効果的に翻訳されました

foo.call(window);

strictモードを使用thisすると、undefined

'use strict';

function foo() {
  console.log(this);
}

foo();  // this is the window object

つまり

言い換えると、

foo();

に効果的に翻訳されました

foo.call(undefined);

JavaScriptには+and -やのような演算子があり*ます。あるドット演算子もあります.

.右側の関数、左側のオブジェクトと共に使用される演算子は、効果的に「パスオブジェクトとしてを意味しますthis関数です。

const bar = {
  name: 'bar',
  foo() { 
    console.log(this); 
  },
};

bar.foo();  // this is bar

言い換えればbar.foo()const temp = bar.foo; temp.call(bar);

関数がどのように作成されたかは関係ありません(ほとんど...)。これらはすべて同じ結果になります

const bar = {
  name: 'bar',
  fn1() { console.log(this); },
  fn2: function() { console.log(this); },
  fn3: otherFunction,
};

function otherFunction() { console.log(this) };

bar.fn1();  // this is bar
bar.fn2();  // this is bar
bar.fn3();  // this is bar

繰り返しますが、これらはすべて構文糖

{ const temp = bar.fn1; temp.call(bar); }
{ const temp = bar.fn2; temp.call(bar); }
{ const temp = bar.fn3; temp.call(bar); }

もう1つのしわは、プロトタイプチェーンです。a.bJavaScript を使用する場合、最初に直接参照されるオブジェクトでaプロパティを探しますbbオブジェクトで見つからない場合、JavaScriptはオブジェクトのプロトタイプを調べて見つけます。b

オブジェクトのプロトタイプを定義するにはさまざまな方法がありますが、2019年に最も一般的なのはclassキーワードです。thisただし、目的には関係ありません。重要なのは、オブジェクトaでプロパティbが見つかった場合はオブジェクトのプロパティを検索bし、最終的bには関数である場合はプロトタイプチェーンで検索するときに、上記と同じルールが適用されることです。関数b参照はcallメソッドを使用して呼び出され、aて呼び出され、この回答の上部に示されているようにobjectForThisとして渡されます。

今。this別の関数を呼び出す前に明示的に設定する関数を作成し、それを.(ドット)演算子で呼び出すとしましょう

function foo() {
  console.log(this);
}

function bar() {
  const objectForThis = {name: 'moo'}
  foo.call(objectForThis);  // explicitly passing objectForThis
}

const obj = {
  bar,
};

obj.bar();  

使用する翻訳に続いてcallobj.bar()となりconst temp = obj.bar; temp.call(obj);ます。bar関数に入ると、呼び出しますfooが、objectForThisの別のオブジェクトを明示的に渡したので、fooに到達するとthisと、その内部オブジェクトになります。

これは、bind=>関数の両方が効果的に行うことです。彼らはより構文的な砂糖です。これらは、指定された関数を呼び出す前にbar明示的に設定thisする、上記とまったく同じ新しい非表示関数を効果的に構築します。bindの場合、this渡したものに設定されますbind

function foo() {
  console.log(this);
}

const bar = foo.bind({name: 'moo'});

// bind created a new invisible function that calls foo with the bound object.

bar();  

// the objectForThis we are passing to bar here is ignored because
// the invisible function that bind created will call foo with with
// the object we bound above

bar.call({name: 'other'});

functionObject.bind存在しなかった場合、このように自分で作成できることに注意してください

function bind(fn, objectForThis) {
  return function(...args) {
    return fn.call(objectForthis, ...args);
  };
}

そして、このように呼ぶことができます

function foo() {
  console.log(this);
}

const bar = bind(foo, {name:'abc'});

矢印関数、=>演算子はバインドの構文糖

const a = () => {console.log(this)};

と同じです

const tempFn = function() {console.log(this)}; 
const a = tempFn.bind(this);

のようにbind、バインドされobjectForThisbindオブジェクトとは異なり、バインドされた値で指定された関数を呼び出す新しい非表示の関数が作成されます。それは何thisが起こっても起こります=>は演算子が使用されたです。

だから、ちょうど上のルールのように

const a = () => { console.log(this); }  // this is the global object
'use strict';
const a = () => { console.log(this); }  // this is undefined
function foo() {
  return () => { console.log(this); }
}

const obj = {
  foo,
};
const b = obj.foo();
b();

obj.foo()変換しconst temp = obj.foo; temp.call(obj);、矢印演算子の内部が意味しているfoo結合するobj新しい不可視の機能にしてに割り当てられていることを新しい不可視の機能を返しますbb()それはいつものように持っているように動作しますb.call(window)b.call(undefined)新しい不可視の機能を呼び出すfoo作成を。この非表示の関数はthis渡された関数を無視し、objobjectForThis`としてarrow関数に渡します。

上記のコードは次のように変換されます

function foo() {
  function tempFn() {
    console.log(this);
  }
  return tempFn.bind(this);
}

const obj = {
  foo,
};
const b = obj.foo();
b.call(window or undefined if strict mode);

1applyは次のような別の関数ですcall

functionName.apply(objectForThis, arrayOfArgs);

しかし、ES6以降では、概念的には次のように変換することもできます。

functionName.call(objectForThis, ...arrayOfArgs);

0

thisJavascriptの概要:

  • の値は、関数が呼び出さthisれた方法ではなく、作成された場所によって決まります
  • 通常、の値thisは、ドットの左側にあるオブジェクトによって決定されます。(windowグローバル空間で)
  • イベントリスナーでは、の値はthis 、イベントが呼び出されたDOM要素を参照します。
  • 関数内でnewキーワードを指定して呼び出すと、値はthis新しく作成されたオブジェクトを参照します
  • あなたは、の値が操作できるthis機能とを:callapplybind

例:

let object = {
  prop1: function () {console.log(this);}
}

object.prop1();   // object is left of the dot, thus this is object

const myFunction = object.prop1 // We store the function in the variable myFunction

myFunction(); // Here we are in the global space
              // myFunction is a property on the global object
              // Therefore it logs the window object
              
             

イベントリスナーの例:

document.querySelector('.foo').addEventListener('click', function () {
  console.log(this);   // This refers to the DOM element the eventListener was invoked from
})


document.querySelector('.foo').addEventListener('click', () => {
  console.log(this);  // Tip, es6 arrow function don't have their own binding to the this v
})                    // Therefore this will log the global object
.foo:hover {
  color: red;
  cursor: pointer;
}
<div class="foo">click me</div>

コンストラクターの例:

function Person (name) {
  this.name = name;
}

const me = new Person('Willem');
// When using the new keyword the this in the constructor function will refer to the newly created object

console.log(me.name); 
// Therefore, the name property was placed on the object created with new keyword.


0

「これ」を正しく理解するには、コンテキストとスコープ、およびそれらの違いを理解する必要があります。

スコープ:JavaScriptスコープでは変数の可視性に関連し、スコープは関数を使用して実現します。(スコープの詳細を読む)

コンテキスト:コンテキストはオブジェクトに関連しています。関数が属するオブジェクトを指します。JavaScriptの「this」キーワードを使用すると、関数が属するオブジェクトを参照します。たとえば、関数内で「this.accoutNumber」と言う場合、その関数が属するオブジェクトに属するプロパティ「accoutNumber」を参照しています。

オブジェクト「myObj」に「getMyName」というメソッドがある場合、JavaScriptキーワード「this」が「getMyName」内で使用されると、「myObj」を参照します。関数「getMyName」がグローバルスコープで実行された場合、「this」はウィンドウオブジェクトを参照します(厳密モードを除く)。

今いくつかの例を見てみましょう:

    <script>
        console.log('What is this: '+this);
        console.log(this);
    </script>

ブラウザー出力のRunnig誤ったコードは次のようになります。 ここに画像の説明を入力してください

ウィンドウオブジェクトのコンテキスト内にある出力によると、ウィンドウプロトタイプがオブジェクトを参照していることもわかります。

次に、関数の内部を試してみましょう。

    <script>
        function myFunc(){
            console.log('What is this: '+this);
            console.log(this);
        }
        myFunc();
    </script>

出力:

ここに画像の説明を入力してください 「this」変数をグローバルスコープに記録し、関数スコープに記録したため、出力は同じです。コンテキストは変更しませんでした。どちらの場合も、未亡人オブジェクトに関連して、コンテキストは同じでした。

次に、独自のオブジェクトを作成します。JavaScriptでは、さまざまな方法でオブジェクトを作成できます。

 <script>
        var firstName = "Nora";
        var lastName = "Zaman";
        var myObj = {
            firstName:"Lord",
            lastName:'Baron',
            printNameGetContext:function(){
                console.log(firstName + " "+lastName);
                console.log(this.firstName +" "+this.lastName);
                return this;
            }
        }

      var context = myObj.printNameGetContext();
      console.log(context);
    </script>

出力: ここに画像の説明を入力してください

上記の例から、「this」キーワードがmyObjに関連する新しいコンテキストを参照していることがわかり、myObjectにもObjectへのプロトタイプチェーンがあります。

別の例を挙げましょう。

<body>
    <button class="btn">Click Me</button>
    <script>
        function printMe(){
            //Terminal2: this function declared inside window context so this function belongs to the window object.
            console.log(this);
        }
        document.querySelector('.btn').addEventListener('click', function(){
            //Terminal1: button context, this callback function belongs to DOM element 
            console.log(this);
            printMe();
        })
    </script>
</body>

出力:理にかなっていますか?(コメントを読む) ここに画像の説明を入力してください

上記の例を理解するのに問題がある場合は、独自のコールバックを試してみましょう。

<script>
        var myObj = {
            firstName:"Lord",
            lastName:'Baron',
            printName:function(callback1, callback2){
                //Attaching callback1 with this myObj context
                this.callback1 = callback1;
                this.callback1(this.firstName +" "+this.lastName)
                //We did not attached callback2 with myObj so, it's reamin with window context by default
                callback2();
                /*
                 //test bellow codes
                 this.callback2 = callback2;
                 this.callback2();
                */
            }
        }
        var callback2 = function (){
            console.log(this);
        }
        myObj.printName(function(data){
            console.log(data);
            console.log(this);
        }, callback2);
    </script>

出力: ここに画像の説明を入力してください

スコープ、セルフ、IIFE、およびこれがどのように動作するかを理解しましょう

       var color = 'red'; // property of window
       var obj = {
           color:'blue', // property of window
           printColor: function(){ // property of obj, attached with obj
               var self = this;
               console.log('In printColor -- this.color: '+this.color);
               console.log('In printColor -- self.color: '+self.color);
               (function(){ // decleard inside of printColor but not property of object, it will executed on window context.
                    console.log(this)
                    console.log('In IIFE -- this.color: '+this.color);
                    console.log('In IIFE -- self.color: '+self.color); 
               })();

               function nestedFunc(){// decleard inside of printColor but not property of object, it will executed on window context.
                    console.log('nested fun -- this.color: '+this.color);
                    console.log('nested fun -- self.color: '+self.color);
               }

               nestedFunc(); // executed on window context
               return nestedFunc;
           }
       };

       obj.printColor()(); // returned function executed on window context
   </script> 

出力はかなり素晴らしいですよね? ここに画像の説明を入力してください


-1

簡単な答え:

「this」キーワードは常に呼び出しのコンテキストに依存します。それらについては以下で説明します。

  1. 関数は新しいキーワードで呼び出されます

    関数がNEWキーワードで呼び出された場合、これは新しく作成されたオブジェクトにバインドされます。

    function Car(){
      this.name="BMW";
    }
    const myCar=new Car();
    myCar.name; // output "BMW"

    上記では、これは「myCar」オブジェクトにバインドされます

  2. 関数は、呼び出しと適用の方法を使用して明示的に呼び出されます。

    この場合、これは明示的に関数に渡されるオブジェクトにバインドされます。

    var obj1={"name":"bond"};
    function printMessage(msg){
        return msg+" "+this.name;
    }
    const message=printMessage.call(obj1,"my name is ");
    console.log(message); //HERE THIS WILL BE BOUND TO obj1 WHICH WE PASSED EXPLICITLY. SAME FOR APPLY METHOD ALSO.
  3. 関数がオブジェクトで暗黙的に呼び出された場合、これはそのオブジェクトに束縛されます

    var obj1={
       "name":"bond",
        getName: function () {
                    return this.name;
                 }
    };
    const newname=obj1.getName();
    console.log(newname); //HERE THIS WILL BE BOUND TO obj1(WHITCHEVER OBJECT IS MENTIONED BEFORE THE DOT THIS WILL BE BOUND TO THAT)
  4. 関数がコンテキストなしで呼び出され、グローバルオブジェクトに束縛される場合

    const util = {
       name: 'Utility',
       getName: function () {
                    return this.name;
    };
    
    const getName=util.getName;
    const newName=getName();
    console.log(newName); // IF THIS EXECUTED IN BROWSER THIS WILL BE  BOUND TO WINDOW OBJECT. IF THIS EXECUTED IN SERVER THIS WILL BE BOUND TO GLOBAL OBJECT
  5. 厳密モードでは、これは未定義になります

    function setName(name){
        "use strict"
        return this.name;
    }
    setName(); //WILL BE ERROR SAYING name IS UNDEFINED. 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.