“this”这个关键字是如何工作的?

我注意到,似乎并没有清楚的解释this关键字是什么,以及它是如何正确(和不正确)在堆栈溢出网站的JavaScript中使用。

我目睹了一些非常奇怪的行为,不明白为什么会发生。

这是如何工作的,什么时候应该使用?

我build议先阅读Mike West的文章Scope in JavaScript ( 镜像 )。 这是一个很好的,友好的介绍this和JavaScript范围链的概念。

一旦你开始习惯this ,规则其实很简单。 ECMAScript标准将其定义为一个关键字:

评估为当前执行上下文的ThisBinding的值;

(§11.1.1)。 ThisBinding是JavaScript解释器在评估JavaScript代码时所维护的东西,就像一个特殊的CPU寄存器,它持有一个对象的引用。 每当build立执行上下文时,解释器都会更新ThisBinding,只有三种情况之一:

  1. 初始全局执行上下文

    对于在遇到<script>元素时评估的JavaScript代码,就是这种情况:

     <script type="text/javascript">//<![CDATA[ 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节)。

  2. input评估代码

    • …通过直接调用eval()

      这个绑定保持不变; 它与调用执行上下文的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(...); var indirectEval = eval; indirectEval(...); 是对eval()的间接调用。 在JavaScript中查看chuckj对(1,eval)('this')和eval('this') 的回答 ? 以及Dmitry Soshnikov撰写的博客文章,您可以使用间接eval()调用。

  3. inputfunction代码

    调用函数时会发生这种情况。 如果某个对象(如obj.myMethod()或等效的obj["myMethod"]()上调用了函数,则将ThisBinding设置为对象(示例中为obj ;第13.2.1节)。 在其他大多数情况下,ThisBinding被设置为全局对象(§10.4.3)。

    写“在大多数情况下”的原因是因为有八个ECMAScript 5内置函数允许在参数列表中指定ThisBinding。 这些特殊函数采用了一个所谓的thisArg ,它在调用函数时成为ThisBinding(第10.4.3节)。

    这些特殊的内置function是:

    • 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函数的情况下,给定的callbackfn在执行上下文中被调用,其中如果提供ThisBinding被设置为thisArg ; 否则,到全局对象。

这些是纯JavaScript的规则。 当你开始使用JavaScript库(例如jQuery)时,你可能会发现某些库函数会操纵这个值。 这些JavaScript库的开发人员这样做是因为它倾向于支持最常见的用例,而库的用户通常会发现这种行为更方便。 当传递引用到库函数的callback函数时,应该参考文档来确定函数被调用时的值是什么。

如果您想知道JavaScript库如何处理这个值,那么库只是使用接受thisArg的内置JavaScript函数之一 。 你也可以编写你自己的函数,使用callback函数和thisArg

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

编辑:

我忘了一个特例。 当通过new运算符构造一个新对象时,JavaScript解释器创build一个新的空对象,设置一些内部属性,然后调用新对象的构造函数。 因此,当一个函数在构造器上下文中被调用时,这个值是解释器创build的新对象:

 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); 

测验只是为了好玩,用下面的例子来testing你的理解。

要显示答案,请将鼠标hover在淡黄色的框中。

  1. A线的价值是什么? 为什么?

     <script type="text/javascript"> if (true) { // Line A } </script> 

    window

    行A在初始全局执行上下文中进行评估。

  2. 在执行obj.staticFunction()时,在B行的值是多less? 为什么?

     <script type="text/javascript"> var obj = { someData: "a string" }; function myFun() { // Line B } obj.staticFunction = myFun; obj.staticFunction(); </script> 

    obj

    在对象上调用函数时,ThisBinding被设置为对象。

  3. C线的价值是什么? 为什么?

     <script type="text/javascript"> var obj = { myMethod : function () { // Line C } }; var myFun = obj.myMethod; myFun(); </script> 

    window

    在这个例子中,JavaScript解释器input函数代码,但是因为myFun / obj.myMethod没有在对象上调用,所以ThisBinding被设置为window

    这不同于Python,其中访问方法( obj.myMethod )创build一个绑定的方法对象 。

  4. D线的价值是什么? 为什么?

     <script type="text/javascript"> function myFun() { // Line D } var obj = { myMethod : function () { eval("myFun()"); } }; obj.myMethod(); </script> 

    window

    这一个是棘手的。 在评估eval代码时, thisobj 。 但是,在eval代码中, myFun不会在对象上调用,因此ThisBinding被设置为调用的window

  5. E线的价值是什么?

     <script type="text/javascript"> function myFun() { // Line E } var obj = { someData: "a string" }; myFun.call(obj); </script> 

    obj

    该行myFun.call(obj); 调用特殊的内置函数Function.prototype.call(),它接受thisArg作为第一个参数。

与其他语言相比, this关键字在JavaScript中的performance有所不同。 在面向对象的语言中, this关键字引用了类的当前实例。 在JavaScript中,这个值主要由函数的调用上下文( 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 

尝试所有的function

我们也可以用function来尝试以上几点。 但是有一些差异。

  • 上面我们使用对象文字符号将成员添加到对象。 我们可以使用this来添加成员函数。 指定它们。
  • 对象文字符号创build一个我们可以立即使用的对象的实例。 有了函数,我们可能需要先使用new运算符来创build它的实例。
  • 同样在对象文字方法中,我们可以使用点运算符显式地将成员添加到已定义的对象。 这只会被添加到特定的实例。 然而,我已经添加了variables的函数原型,以便它反映在该函数的所有实例。

下面我尝试了所有的事情,我们做了对象和上面this ,但首先创buildfunction,而不是直接写一个对象。

 /********************************************************************* 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.内部调用(),apply()和bind()函数

  • 所有这些方法都是在Function.prototype上定义的。
  • 这些方法允许编写一个函数,并在不同的上下文中调用它。 换句话说,它们允许指定在执行函数时使用的值。 当它被调用时,它们还可以将任何parameter passing给原始函数。
  • fun.apply(obj1 [, argsArray]) obj1设置为fun()内的值,并调用fun()传递argsArray元素作为其参数。
  • fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) – 将obj1设置为fun()内的值,并调用fun()传递arg1, arg2, arg3, ...作为论据。
  • fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) – 返回对函数fun的引用, this内部乐趣绑定到obj1并将fun参数绑定到指定的参数arg1, arg2, arg3,...
  • 现在, applycallbind之间的差异已经变得明显。 apply允许指定参数作为类似数组的对象,即具有数字length属性和相应的非负整数属性的对象。 而call允许直接指定函数的参数。 同时applycall立即调用指定的上下文中的函数和指定的参数。 另一方面, bind只是返回绑定到指定的this值和参数的函数。 我们可以通过将其分配给一个variables来捕获对此返回函数的引用,随后我们可以随时调用它。
 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 = // `oa` ie 4 + 5 + 6 = 15 document.write(add.apply(o, [5, 6]) + "<br />"); //15 // `oa` ie 4 + 5 + 6 = 15 var g = add.bind(o, 5, 6); //g: `oa` ie 4 + 5 + 6 document.write(g()+"<br />"); //15 var h = add.bind(o, 5); //h: `oa` ie 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来完成这种直接的函数分配。
  • 同样,当你在元素的事件属性(如<button onclick="...this..." > )中直接使用它时,它指向元素。
  • 但是,通过在事件处理函数或事件属性内部调用的其他函数间接使用this则会parsing为全局对象window
  • 当我们使用Microsoft的事件注册模型方法attachEvent将该函数附加到事件处理函数时,可以实现上述相同的行为。 它不是将函数分配给事件处理函数(并因此使得元素的函数方法),而是调用事件上的函数(在全局上下文中有效地调用它)。

我build议在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> 

“这个”是关于范围的。 每个函数都有它自己的范围,因为JS中的所有东西都是一个对象,即使是一个函数也可以用“this”来存储一些值。 OOP 101教导“这个”仅适用于对象的实例 。 因此,每执行一次函数,该函数的新“实例”就具有“this”的新含义。

当大多数人尝试在匿名封闭函数中使用“this”时会感到困惑:

 (function(value){
     this.value = value;
     $(”。一些元素)。每个(函数(ELT){
         elt.innerHTML = this.value;  //哦,哦! 可能未定义
     });
 })(2);

所以在这里,在每个()里面,“this”并不包含你所期望的“值”

  this.value = value; 

它上面)。 所以,为了克服这个问题(不是双关语),开发者可以:

 (function(value){
     var self = this;  // 小变化
     self.value = value;
     $(”。一些元素)。每个(函数(ELT){
         elt.innerHTML = self.value;  //唷!  == 2 
     });
 })(2);

试试看; 你会开始喜欢这种编程模式

Javascript的this

简单的函数调用

考虑以下function:

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

请注意,我们正在正常模式下运行,即不使用严格模式。

当在浏览器中运行时,其值将被logging为window 。 这是因为window是Web浏览器范围内的全局variables。

如果你在像node.js this的环境中运行这个相同的代码, this将引用你的应用程序中的全局variables。

现在,如果我们通过添加语句"use strict";在严格模式下运行此操作, 到函数声明的开头, this将不再引用任何一个环境中的全局variables。 这样做是为了避免在严格模式下的混淆。 this将在这种情况下只是日志undefined ,因为这是它是什么,它没有被定义。

在下面的情况下,我们会看到如何操作这个值。

调用对象上的函数

有不同的方法来做到这一点。 如果你已经在Javascript中调用了native方法,比如forEachslice ,那么你应该已经知道thisvariables是指你调用该函数的Object (请注意,在JavaScript中,几乎所有东西都是Object ,包括ArrayFunction s)。 以下面的代码为例。

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

如果一个Object包含一个拥有一个Function的属性,那么这个属性被称为一个方法。 这个方法在被调用的时候,总是会把thisvariables设置为它所关联的Object 。 严格模式和非严格模式都是如此。

请注意,如果一个方法被存储(或者说,被复制)到另一个variables中,那么thisvariables的引用将不再保存在新variables中。 例如:

 // continuing with the previous code snippet var myVar = myObj.thisMethod; 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关键字调用函数将立即初始化Persontypes的Object
  2. Object的构造函数将其构造函数设置为Person 。 另外,请注意typeof awal只会返回Object
  3. 这个新的Object将被赋予Person.prototype的原型。 这意味着Person原型中的任何方法或属性都可用于Person所有实例,包括awal
  4. Person本身现在被调用; this是对新构build的对象awal

相当直接,呃?

请注意官方的ECMAScript规范没有说明这种types的函数是实际的constructor函数。 他们只是正常的function, newfunction可以用于任何function。 只是我们这样使用它们,所以我们只是这样称呼它们。

调用函数function: callapply

所以是的,因为function也是Objects (事实上​​,在Javascript中的第一类variables),甚至函数有方法…好,function它们。

所有函数都从全局函数inheritance,其中的两个方法是callapply ,二者都可用于在调用函数时调用它的值。

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

这是使用call的典型示例。 它基本上采用第一个参数,并在函数foo中将其设置为thisArg的引用。 传递给call所有其他参数作为parameter passing给函数foo
所以上面的代码会在控制台中logging{myObj: "is cool"}, [1, 2, 3] 。 很好的方法来改变任何函数中的值。

applycall几乎相同,只接受两个参数: thisArg和一个包含要传递给函数的参数的数组。 所以上面的call可以翻译成这样apply

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

请注意, callapply可以通过我们在第二个项目符号中讨论的点方法调用来覆盖this集合的值。 简单:)

呈现…. bind

bind是一个callapply的兄弟。 它也是Javascript中全局Function构造函数的所有函数inheritance的方法。 bindcall / apply的区别在于callapply都会调用这个函数。 bind ,另一方面,返回一个新的函数与thisArgarguments预先设置。 我们举个例子来更好地理解这个:

 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]` 

看到三者之间的区别? 这是微妙的,但他们使用不同。 像callapply一样, bind也会通过点方法调用覆盖this集合的值。

还要注意,这三个函数都没有对原始函数做任何改变。 callapply将返回新构造的函数的值,而bind将返回刚刚构build的函数本身,准备调用。

额外的东西,复制这个

有时候,你不喜欢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值。 所以我们“复制”到that并使用副本,而不是this 。 聪明,呃?

指数:

  1. 默认情况下是什么?
  2. 如果我们把这个函数作为一个Object-dot记法的方法呢?
  3. 如果我们使用new关键字呢?
  4. 我们如何操纵this callapply
  5. 使用bind
  6. 复制this解决嵌套范围的问题。

由于这个线索已经出现了,我为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); } } 

直到一个对象调用它定义的函数时才会赋值 。 在全局范围内,所有全局variables和函数都在window对象上定义。 因此, this在全局函数中是指全局window对象(并具有其值)。

When use strict , this in global and in anonymous functions that are not bound to any object holds a value of undefined .

The this keyword is most misunderstood when: 1) we borrow a method that uses this , 2) we assign a method that uses this to a variable, 3) a function that uses this is passed as a callback function, and 4) this is used inside a closure — an inner function. (2)

表

What holds the future

Defined in ECMA Script 6 , arrow-functions adopt the this binding from the enclosing (function or global) scope.

 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! 

While arrow-functions provide an alternative to using bind() , it's important to note that they essentially are disabling the traditional this mechanism in favor of more widely understood lexical scoping. (1)


参考文献:

  1. this & Object Prototypes , by Kyle Simpson. © 2014 Getify Solutions.
  2. javascriptissexy.com – http://goo.gl/pvl0GX
  3. Angus Croll – http://goo.gl/Z2RacU

this in Javascript always refers to the 'owner' of the function that is being executed .

If no explicit owner is defined, then the top most owner, the window object, is referenced.

So if I did

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

element.onclick = someKindOfFunction;

this would refer to the element object. But be careful, a lot of people make this mistake

<element onclick="someKindOfFunction()">

In the latter case, you merely reference the function, not hand it over to the element. Therefor, this will refer to the window object.

Here is one good source of this in JavaScript .

Here is the summary:

  • global this

    In a browser, at the global scope, this is the window object

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

    In node using the repl, this is the top namespace. You can refer to it as global .

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

    In node executing from a script, this at the global scope starts as an empty object. It is not the same as global

     \\test.js console.log(this); \\ {} console.log(this === global); \\ fasle 
  • function this

Except in the case of DOM event handlers or when a thisArg is provided (see further down), both in node and in a browser using this in a function that is not called with new references the global scope…

 <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> 

If you use use strict; , in which case this will be undefined

 <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> 

If you call a function with new the this will be a new context, it will not reference the global this .

 <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 this

Functions you create become function objects. They automatically get a special prototype property, which is something you can assign values to. When you create an instance by calling your function with new you get access to the values you assigned to the prototype property. You access those values using this .

 function Thing() { console.log(this.foo); } Thing.prototype.foo = "bar"; var thing = new Thing(); //logs "bar" console.log(thing.foo); //logs "bar" 

It is usually a mistake to assign arrays or objects on the prototype . If you want instances to each have their own arrays, create them in the function, not the 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 [] 
  • object this

You can use this in any function on an object to refer to other properties on that object. This is not the same as an instance created with new .

 var obj = { foo: "bar", logFoo: function () { console.log(this.foo); } }; obj.logFoo(); //logs "bar" 
  • DOM event this

In an HTML DOM event handler, this is always a reference to the DOM element the event was attached to

 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(); 

Unless you bind the context

 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 this

Inside HTML attributes in which you can put JavaScript, this is a reference to the element.

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

You can use eval to access this .

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

You can use with to add this to the current scope to read and write to values on this without referring to this explicitly.

 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

the jQuery will in many places have this refer to a DOM element.

 <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> 

Every function execution context in javascript has a scope context this parameter that is set by:

  1. How the function is called (including as an object method, use of call and apply , use of new )
  2. Use of bind
  3. Lexically for arrow functions (they adopt the this of their outer execution context)

Whatever that scope context is, is referenced by "this".

You can change that set the value of this scope context using func.call , func.apply or func.bind .

By default, and what confuses most beginners, when a callback listener is called after an event is raised on a DOM element, the scope context this value of the function is the DOM element.

jQuery makes this trivial to change with jQuery.proxy.

Daniel, awesome explanation! A couple of words on this and good list of this execution context pointer in case of event handlers.

In two words, this in JavaScript points the object from whom (or from whose execution context) the current function was run and it's always read-only, you can't set it anyway (such an attempt will end up with 'Invalid left-hand side in assignment' message.

For event handlers: inline event handlers, such as <element onclick="foo"> , override any other handlers attached earlier and before, so be careful and it's better to stay off of inline event delegation at all. And thanks to Zara Alaverdyan who inspired me to this list of examples through a dissenting debate 🙂

  • 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)">

It is difficult to get a good grasp of JS, or write more than anything trivial in it, if you don't understand it thoroughly. You cannot just afford to take a quick dip 🙂 I think the best way to get started with JS is to first watch these video lectures by Douglas Crockford – http://yuiblog.com/crockford/ , which covers this and that, and everything else about JS.

This is the best explanation I've seen. Understand JavaScripts this with Clarity

The this reference ALWAYS refers to (and holds the value of) an object—a singular object—and it is usually used inside a function or a method, although it can be used outside a function in the global scope. Note that when we use strict mode, this holds the value of undefined in global functions and in anonymous functions that are not bound to any object.

There are Four Conditions where this can be confusing:

  1. When we pass a method (that uses this ) as a parameter to be used as a callback function.
  2. Another instance when this is misunderstood is when we use an inner method (a closure). It is important to take note that closures cannot access the outer function's this variable by using the this keyword because the this variable is accessible only by the function itself, not by inner functions.
  3. Using this when a method is assigned to a variable. The this value is bound to another object, if we assign a method that uses this to a variable
  4. Using this when using bind, apply, and call methods.

He gives code examples, the explanations, and the code fixes which I thought was very helpful.

this is one of the misunderstood concept in JavaScript because it behaves little differently from place to place. Simply, this refers to the "owner" of the function we are currently executing .

this helps to get the current object (aka execution context) we work with. If you understand in which object the current function is getting executed, you can understand easily what current this is

 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 

Above we create 3 variables with same name 'val'. One in global context, one inside obj and the other inside innerMethod of obj. JavaScript resolves identifiers within a particular context by going up the scope chain from local go global.


Few places where this can be differentiated

Calling a method of a object

 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 

When line1 is executed, JavaScript establishes an execution context (EC) for the function call, setting this to the object referenced by whatever came before the last "." 。 so in the last line you can understand that a() was executed in the global context which is the window .

With Constructor

this can be used to refer to the object being created

 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 

When new Person() is executed, a completely new object is created. Person is called and its this is set to reference that new object.

Function call

 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 

If we miss new keyword, whatIsThis referes to the most global context it can find( window )

With event handlers

If the event handler is inline, this refers to global object

 <script type="application/javascript"> function click_handler() { alert(this); // alerts the window object } </script> <button id='thebutton' onclick='click_handler()'>Click me!</button> 

When adding event handler through JavaScript, this refers to DOM element that generated the event.


  • You can also manipulate the context using .apply() .call() and .bind()
  • JQuery proxy is another way you can use to make sure this in a function will be the value you desire. (Check Understanding $.proxy() , jQuery.proxy() usage )
  • What does var that = this means in JavaScript

Probably the most detailed and comprehensive article on this is the following:

Gentle explanation of 'this' keyword in JavaScript

The idea behind this is to understand that the function invocation types have the significant importance on setting this value.


When having troubles identifying this , do not ask yourself:

Where is this taken from ?

but do ask yourself:

How is the function invoked ?

For an arrow function (special case of context transparency) ask yourself:

What value has this where the arrow function is defined ?

This mindset is correct when dealing with this and will save you from headache.

There is a lot of confusion regarding how "this" keyword is interpreted in JavaScript. Hopefully this article will lay all those to rest once and for all. 还有更多。 Please read the entire article carefully. Be forewarned that this article is long.

Irrespective of the context in which it is used, "this" always references the "current object" in Javascript. However, what the "current object" is differs according to context . The context may be exactly 1 of the 6 following:

  1. Global (ie Outside all functions)
  2. Inside Direct "Non Bound Function" Call (ie a function that has not been bound by calling functionName.bind )
  3. Inside Indirect "Non Bound Function" Call through functionName.call and functionName.apply
  4. Inside "Bound Function" Call (ie a function that has been bound by calling functionName.bind )
  5. While Object Creation through "new"
  6. Inside Inline DOM event handler

The following describes each of this contexts one by one:

  1. Global Context (ie Outside all functions):

    Outside all functions (ie in global context) the "current object" (and hence the value of "this" ) is always the "window" object for browsers.

  2. Inside Direct "Non Bound Function" Call :

    Inside a Direct "Non Bound Function" Call, the object that invoked the function call becomes the "current object" (and hence the value of "this" ). If a function is called without a explicit current object , the current object is either the "window" object (For Non Strict Mode) or undefined (For Strict Mode) . Any function (or variable) defined in Global Context automatically becomes a property of the "window" object.For eg Suppose function is defined in Global Context as

     function UserDefinedFunction(){ alert(this) } 

    it becomes the property of the window object, as if you have defined it as

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

    In "Non Strict Mode", Calling/Invoking this function directly through "UserDefinedFunction()" will automatically call/invoke it as "window.UserDefinedFunction()" making "window" as the "current object" (and hence the value of "this" ) within "UserDefinedFunction" .Invoking this function in "Non Strict Mode" will result in the following

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

    In "Strict Mode", Calling/Invoking the function directly through "UserDefinedFunction()" will "NOT" automatically call/invoke it as "window.UserDefinedFunction()" .Hence the "current object" (and the value of "this" ) within "UserDefinedFunction" shall be undefined . Invoking this function in "Strict Mode" will result in the following

     UserDefinedFunction() // displays undefined 

    However, invoking it explicitly using window object shall result in the following

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

    Let us look at another example. Please look at the following code

      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 

    In the above example we see that when "UserDefinedFunction" was invoked through o1 , "this" takes value of o1 and the value of its properties "a" and "b" get displayed. The value of "c" and "d" were shown as undefined as o1 does not define these properties

    Similarly when "UserDefinedFunction" was invoked through o2 , "this" takes value of o2 and the value of its properties "c" and "d" get displayed.The value of "a" and "b" were shown as undefined as o2 does not define these properties.

  3. Inside Indirect "Non Bound Function" Call through functionName.call and functionName.apply :

    When a "Non Bound Function" is called through functionName.call or functionName.apply , the "current object" (and hence the value of "this" ) is set to the value of "this" parameter (first parameter) passed to call/apply . The following code demonstrates the same.

     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 

    The above code clearly shows that the "this" value for any "NON Bound Function" can be altered through call/apply . Also,if the "this" parameter is not explicitly passed to call/apply , "current object" (and hence the value of "this") is set to "window" in Non strict mode and "undefined" in strict mode.

  4. Inside "Bound Function" Call (ie a function that has been bound by calling functionName.bind ):

    A bound function is a function whose "this" value has been fixed. The following code demonstrated how "this" works in case of bound function

     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 

    As given in the code above, "this" value for any "Bound Function" CANNOT be altered through call/apply . Also, if the "this" parameter is not explicitly passed to bind, "current object" (and hence the value of "this" ) is set to "window" in Non strict mode and "undefined" in strict mode. 还有一件事。 Binding an already bound function does not change the value of "this" . It remains set as the value set by first bind function.

  5. While Object Creation through "new" :

    Inside a constructor function, the "current object" (and hence the value of "this" ) references the object that is currently being created through "new" irrespective of the bind status of the function. However if the constructor is a bound function it shall get called with predefined set of arguments as set for the bound function.

  6. Inside Inline DOM event handler :

    Please look at the following HTML Snippet

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

    The "this" in above examples refer to "button" element and the "div" element respectively.

    In the first example, the font color of the button shall be set to white when it is clicked.

    In the second example when the "div" element is clicked it shall call the OnDivClick function with its second parameter referencing the clicked div element. However the value of "this" within OnDivClick SHALL NOT reference the clicked div element. It shall be set as the "window object" or "undefined" in Non strict and Strict Modes respectively (if OnDivClick is an unbound function ) or set to a predefined Bound value (if OnDivClick is a bound function )

The following summarizes the entire article

  1. In Global Context "this" always refers to the "window" object

  2. Whenever a function is invoked, it is invoked in context of an object ( "current object" ). If the current object is not explicitly provided, the current object is the "window object" in NON Strict Mode and "undefined" in Strict Mode by default.

  3. The value of "this" within a Non Bound function is the reference to object in context of which the function is invoked ( "current object" )

  4. The value of "this" within a Non Bound function can be overriden by call and apply methods of the function.

  5. The value of "this" is fixed for a Bound function and cannot be overriden by call and apply methods of the function.

  6. Binding and already bound function does not change the value of "this". It remains set as the value set by first bind function.

  7. The value of "this" within a constructor is the object that is being created and initialized

  8. The value of "this" within an inline DOM event handler is reference to the element for which the event handler is given.

Whould this help? (Most confusion of 'this' in javascript is coming from the fact that it generally is not linked to your object, but to the current executing scope — that might not be exactly how it works but is always feels like that to me — see the article for a complete explanation)

this use for Scope just like this

  <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> 

value of txt1 and txt is same in Above example $(this)=$('#tbleName tbody tr') is Same

"this" is all about scope. Every function has its own scope, and since everything in JS is an object, even a function can store some values into itself using "this".

 $('#a').click(function(){ console.log($(this).attr('href')); }); 

The value of "this" depends on the "context" in which the function is executed. The context can be any object or the global object, ie, window.

So the Semantic of "this" is different from the traditional OOP languages. And it causes problems: 1. when a function is passed to another variable (most likely, a callback); and 2. when a closure is invoked from a member method of a class.

In both cases, this is set to window.

In pseudoclassical terms, the way many lectures teach the 'this' keyword is as an object instantiated by a class or object constructor. Each time a new object is constructed from a class, imagine that under the hood a local instance of a 'this' object is created and returned. I remember it taught like 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;