Javascript “this”关键字如何工作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3127429/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does the "this" keyword work?
提问by Maxim Gershkovich
I have noticed that there doesn't appear to be a clear explanation of what the thiskeyword is and how it is correctly (and incorrectly) used in JavaScript on the Stack Overflow site.
我注意到thisStack Overflow 网站上似乎没有明确解释关键字是什么以及它是如何在 JavaScript 中正确(和错误地)使用的。
I have witnessed some very strange behaviour with it and have failed to understand why it has occurred.
我目睹了它的一些非常奇怪的行为,并且无法理解它为什么会发生。
How does thiswork and when should it be used?
如何this工作以及何时应该使用它?
回答by Daniel Trebbien
I recommend reading Mike West's article Scope in JavaScript(mirror) first. It is an excellent, friendly introduction to the concepts of thisand scope chains in JavaScript.
我建议先阅读Mike West的文章Scope in JavaScript( mirror)。这是对thisJavaScript 中作用域链和作用域链概念的出色而友好的介绍。
Once you start getting used to this, the rules are actually pretty simple. The ECMAScript 5.1 Standarddefines this:
一旦你开始习惯this,规则其实很简单。所述的ECMAScript 5.1标准定义this:
§11.1.1The
thiskeywordThe
thiskeyword evaluates to the value of the ThisBinding of the current execution context
§11.1.1的
this关键字所述
this关键字的计算结果为当前执行上下文的ThisBinding的值
ThisBinding is something that the JavaScript interpreter maintains as it evaluates JavaScript code, like a special CPU register which holds a reference to an object. The interpreter updates the ThisBinding whenever establishing an execution context in one of only three different cases:
ThisBinding 是 JavaScript 解释器在评估 JavaScript 代码时维护的东西,就像一个特殊的 CPU 寄存器,它保存对对象的引用。每当在以下三种不同情况之一中建立执行上下文时,解释器都会更新 ThisBinding:
1. Initial global execution context
1. 初始全局执行上下文
This is the case for JavaScript code that is evaluated at the top-level, e.g. when directly inside a <script>:
这是在顶级评估的 JavaScript 代码的情况,例如直接在 a 内部时<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>
When evaluating code in the initial global execution context, ThisBinding is set to the global object, window(§10.4.1.1).
在初始全局执行上下文中评估代码时,ThisBinding 设置为全局对象window(第10.4.1.1 节)。
Entering eval code
输入评估代码
…by a direct call to
eval()ThisBinding is left unchanged; it is the same value as the ThisBinding of the calling execution context (§10.4.2(2)(a)).…if not by a direct call to
eval()
ThisBinding is set to the global object as ifexecuting in the initial global execution context (§10.4.2(1)).
...通过直接调用
eval()ThisBinding 保持不变;它与调用执行上下文的 ThisBinding 值相同(§10.4.2(2)(a))。...如果不是通过直接调用
eval()
ThisBinding 设置为全局对象,就像在初始全局执行上下文中执行一样(第10.4.2(1) 节)。
§15.1.2.1.1 defines what a direct call to eval()is. Basically, eval(...)is a direct call whereas something like (0, eval)(...)or var indirectEval = eval; indirectEval(...);is an indirect call to eval(). See chuckj's answerto (1, eval)('this') vs eval('this') in JavaScript?and Dmitry Soshnikov's ECMA-262-5 in detail. Chapter 2. Strict Mode.for when you might use an indirect eval()call.
§15.1.2.1.1 定义了直接调用eval()是什么。基本上,eval(...)是直接调用,而类似于(0, eval)(...)或var indirectEval = eval; indirectEval(...);间接调用eval(). 在 JavaScript 中看到Chukj对(1, eval)('this') 与 eval('this')的回答吗?和Dmitry Soshnikov 的 ECMA-262-5 详细说明。第 2 章严格模式。什么时候可以使用间接eval()调用。
Entering function code
输入功能码
This occurs when calling a function. If a function is called on an object, such as in obj.myMethod()or the equivalent obj["myMethod"](), then ThisBinding is set to the object (objin the example; §13.2.1). In most other cases, ThisBinding is set to the global object (§10.4.3).
调用函数时会发生这种情况。如果在对象上调用函数,例如 inobj.myMethod()或等效的obj["myMethod"](),则将 ThisBinding 设置为该对象(obj在示例中;第13.2.1 节)。在大多数其他情况下,ThisBinding 设置为全局对象(第10.4.3 节)。
The reason for writing "in most other cases" is because there are eight ECMAScript 5 built-in functions that allow ThisBinding to be specified in the arguments list. These special functions take a so-called thisArgwhich becomes the ThisBinding when calling the function (§10.4.3).
编写“在大多数其他情况下”的原因是因为有八个 ECMAScript 5 内置函数允许在参数列表中指定 ThisBinding。这些特殊函数thisArg在调用函数时采用所谓的 ThisBinding(第10.4.3 节)。
These special built-in functions are:
这些特殊的内置函数是:
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.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 ] )
In the case of the Function.prototypefunctions, they are called on a function object, but rather than setting ThisBinding to the function object, ThisBinding is set to the thisArg.
在Function.prototype函数的情况下,它们是在函数对象上调用的,但不是将 ThisBinding 设置为函数对象,而是将 ThisBinding 设置为thisArg.
In the case of the Array.prototypefunctions, the given callbackfnis called in an execution context where ThisBinding is set to thisArgif supplied; otherwise, to the global object.
在Array.prototype函数的情况下,给定callbackfn在执行上下文中调用,其中 ThisBinding 设置为thisArgif 提供;否则,到全局对象。
Those are the rules for plain JavaScript. When you begin using JavaScript libraries (e.g. jQuery), you may find that certain library functions manipulate the value of this. The developers of those JavaScript libraries do this because it tends to support the most common use cases, and users of the library typically find this behavior to be more convenient. When passing callback functions referencing thisto library functions, you should refer to the documentation for any guarantees about what the value of thisis when the function is called.
这些是纯 JavaScript 的规则。当您开始使用 JavaScript 库(例如 jQuery)时,您可能会发现某些库函数会操作this. 这些 JavaScript 库的开发人员这样做是因为它倾向于支持最常见的用例,并且库的用户通常会发现这种行为更方便。当传递引用this库函数的回调函数时,您应该参考文档以获取有关this调用函数时的值的任何保证。
If you are wondering how a JavaScript library manipulates the value of this, the library is simply using one of the built-in JavaScript functions accepting a thisArg. You, too, can write your own function taking a callback function and thisArg:
如果您想知道 JavaScript 库如何操作 的值this,该库只是使用一个内置的 JavaScript 函数接受thisArg. 您也可以编写自己的带有回调函数的函数,并且thisArg:
function doWork(callbackfn, thisArg) {
//...
if (callbackfn != null) callbackfn.call(thisArg);
}
There's a special case I didn't yet mention. When constructing a new object via the newoperator, the JavaScript interpreter creates a new, empty object, sets some internal properties, and then calls the constructor function on the new object. Thus, when a function is called in a constructor context, the value of thisis the new object that the interpreter created:
有一个特殊情况我还没有提到。当通过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);
Arrow functions
箭头函数
Arrow functions(introduced in ECMA6) alter the scope of this. See the existing canonical question, Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?for more information. But in short:
箭头函数(在 ECMA6 中引入)改变了this. 请参阅现有的规范问题,箭头函数与函数声明/表达式:它们是否等效/可交换?想要查询更多的信息。但简而言之:
Arrow functions don't have their own
this.... binding. Instead, those identifiers are resolved in the lexical scope like any other variable. That means that inside an arrow function,this...refer(s) to the values ofthisin the environment the arrow function is defined in.
箭头函数没有自己的
this.... 绑定。相反,这些标识符像任何其他变量一样在词法范围内解析。这意味着在箭头函数内部,this...引用(s)到this定义箭头函数的环境中的值。
Just for fun, test your understanding with some examples
只是为了好玩,用一些例子测试你的理解
To reveal the answers, mouse over the light grey boxes.
要显示答案,请将鼠标悬停在浅灰色框上。
What is the value of
thisat the marked line? Why?window— The marked line is evaluated in the initial global execution context.if (true) { // What is `this` here? }What is the value of
thisat the marked line whenobj.staticFunction()is executed? Why?obj— When calling a function on an object, ThisBinding is set to the object.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);What is the value of
thisat the marked line? Why?windowIn this example, the JavaScript interpreter enters function code, but because
myFun/obj.myMethodis not called on an object, ThisBinding is set towindow.This is different from Python, in which accessing a method (
obj.myMethod) creates a bound method object.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);What is the value of
thisat the marked line? Why?windowThis one was tricky. When evaluating the eval code,
thisisobj. However, in the eval code,myFunis not called on an object, so ThisBinding is set towindowfor the call.function myFun() { return this; // What is `this` here? } var obj = { myMethod: function () { eval("myFun()"); } };What is the value of
thisat the marked line? Why?objThe line
myFun.call(obj);is invoking the special built-in functionFunction.prototype.call(), which acceptsthisArgas the first argument.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);
this标记线上的值是多少?为什么?window— 标记的行在初始全局执行上下文中进行评估。if (true) { // What is `this` here? }执行
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);this标记线上的值是多少?为什么?window在此示例中,JavaScript 解释器输入函数代码,但由于未在对象上调用
myFun/obj.myMethod,因此将 ThisBinding 设置为window。这与 Python 不同,在 Python 中,访问方法 (
obj.myMethod) 创建绑定的方法对象。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);this标记线上的值是多少?为什么?window这个很棘手。在评估 eval 代码时,
this是obj. 但是,在 eval 代码中,myFun并没有在对象上调用,因此将 ThisBinding 设置为window用于调用。function myFun() { return this; // What is `this` here? } var obj = { myMethod: function () { eval("myFun()"); } };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);
回答by Mahesha999
The thiskeyword behaves differently in JavaScript compared to other languages. In Object Oriented languages, the thiskeyword refers to the current instance of the class. In JavaScript the value of thisis determined by the invocation context of function (context.function()) and where it is called.
this与其他语言相比,该关键字在 JavaScript 中的行为有所不同。在面向对象的语言中,this关键字指的是类的当前实例。在 JavaScript 中, 的值this由函数 ( context.function())的调用上下文和调用位置决定。
1. When used in global context
1. 在全局上下文中使用时
When you use thisin global context, it is bound to global object (windowin browser)
this在全局上下文中使用时,它绑定到全局对象(window在浏览器中)
document.write(this); //[object Window]
When you use thisinside a function defined in the global context, thisis still bound to global object since the function is actually made a method of global context.
当您this在全局上下文中定义的函数内部使用时,this仍然绑定到全局对象,因为该函数实际上是一个全局上下文的方法。
function f1()
{
return this;
}
document.write(f1()); //[object Window]
Above f1is made a method of global object. Thus we can also call it on windowobject as follows:
上面f1做了一个全局对象的方法。因此,我们也可以在window对象上调用它,如下所示:
function f()
{
return this;
}
document.write(window.f()); //[object Window]
2. When used inside object method
2. 在对象方法内部使用时
When you use thiskeyword inside an object method, thisis bound to the "immediate" enclosing object.
当您this在对象方法中使用关键字时,this会绑定到“立即”封闭对象。
var obj = {
name: "obj",
f: function () {
return this + ":" + this.name;
}
};
document.write(obj.f()); //[object Object]:obj
Above I have put the word immediate in double quotes. It is to make the point that if you nest the object inside another object, then thisis bound to the immediate parent.
上面我将立即这个词放在双引号中。这是为了说明如果将对象嵌套在另一个对象中,则this绑定到直接父对象。
var obj = {
name: "obj1",
nestedobj: {
name:"nestedobj",
f: function () {
return this + ":" + this.name;
}
}
}
document.write(obj.nestedobj.f()); //[object Object]:nestedobj
Even if you add function explicitly to the object as a method, it still follows above rules, that is thisstill points to the immediate parent object.
即使您将函数作为方法显式添加到对象中,它仍然遵循上述规则,即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. When invoking context-less function
3. 调用无上下文函数时
When you use thisinside function that is invoked without any context (i.e. not on any object), it is bound to the global object (windowin browser)(even if the function is defined inside the object) .
当您使用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
Trying it all with functions
尝试所有功能
We can try above points with functions too. However there are some differences.
我们也可以用函数来尝试以上几点。但是,存在一些差异。
- Above we added members to objects using object literal notation. We can add members to functions by using
this. to specify them. - Object literal notation creates an instance of object which we can use immediately. With function we may need to first create its instance using
newoperator. - Also in an object literal approach, we can explicitly add members to already defined object using dot operator. This gets added to the specific instance only. However I have added variable to the function prototype so that it gets reflected in all instances of the function.
- 上面我们使用对象文字符号向对象添加成员。我们可以使用 向函数添加成员
this。来指定它们。 - 对象文字表示法创建了一个我们可以立即使用的对象实例。对于函数,我们可能需要首先使用
new运算符创建它的实例。 - 同样在对象文字方法中,我们可以使用点运算符将成员显式添加到已定义的对象中。这只会添加到特定实例。但是,我已将变量添加到函数原型中,以便它反映在函数的所有实例中。
Below I tried out all the things that we did with Object and thisabove, but by first creating function instead of directly writing an object.
下面我尝试了我们对 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. When used inside constructor function.
4. 在构造函数内部使用时。
When the function is used as a constructor (that is when it is called with newkeyword), thisinside function body points to the new object being constructed.
当函数用作构造函数时(即使用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. When used inside function defined on prototype chain
5. 在原型链上定义的函数内部使用时
If the method is on an object's prototype chain, thisinside such method refers to the object the method was called on, as if the method is defined on the object.
如果该方法位于对象的原型链上,则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. Inside call(), apply() and bind() functions
6. 在 call()、apply() 和 bind() 函数内部
- All these methods are defined on
Function.prototype. - These methods allows to write a function once and invoke it in different context. In other words, they allows to specify the value of
thiswhich will be used while the function is being executed. They also take any parameters to be passed to the original function when it is invoked. fun.apply(obj1 [, argsArray])Setsobj1as the value ofthisinsidefun()and callsfun()passing elements ofargsArrayas its arguments.fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])- Setsobj1as the value ofthisinsidefun()and callsfun()passingarg1, arg2, arg3, ...as its arguments.fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])- Returns the reference to the functionfunwiththisinside fun bound toobj1and parameters offunbound to the parameters specifiedarg1, arg2, arg3,....- By now the difference between
apply,callandbindmust have become apparent.applyallows to specify the arguments to function as array-like object i.e. an object with a numericlengthproperty and corresponding non-negative integer properties. Whereascallallows to specify the arguments to the function directly. Bothapplyandcallimmediately invokes the function in the specified context and with the specified arguments. On the other hand,bindsimply returns the function bound to the specifiedthisvalue and the arguments. We can capture the reference to this returned function by assigning it to a variable and later we can call it any time.
- 所有这些方法都在 上定义
Function.prototype。 - 这些方法允许编写一次函数并在不同的上下文中调用它。换句话说,它们允许指定在
this执行函数时将使用的值。当调用原始函数时,它们还会将任何参数传递给原始函数。 fun.apply(obj1 [, argsArray])设置obj1为thisinside的值fun()并调用fun()传递的元素argsArray作为其参数。fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])- 设置obj1为thisinside的值fun()并调用作为其参数的fun()传递arg1, arg2, arg3, ...。fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])-返回参照功能fun与this必然中的乐趣obj1和参数fun绑定到指定的参数arg1, arg2, arg3,...。- 到现在为止
apply,call和之间的区别bind应该已经很明显了。apply允许将参数指定为类似数组的对象,即具有数字length属性和相应的非负整数属性的对象。而call允许直接指定函数的参数。双方apply并call立即调用函数中指定的上下文和用指定的参数。另一方面,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. thisinside event handlers
7.this内部事件处理程序
- When you assign function directly to event handlers of an element, use of
thisdirectly inside event handling function refers to the corresponding element. Such direct function assignment can be done usingaddeventListenermethod or through the traditional event registration methods likeonclick. - Similarly, when you use
thisdirectly inside the event property (like<button onclick="...this..." >) of the element, it refers to the element. - However use of
thisindirectly through the other function called inside the event handling function or event property resolves to the global objectwindow. - The same above behavior is achieved when we attach the function to the event handler using Microsoft's Event Registration model method
attachEvent. Instead of assigning the function to the event handler (and the thus making the function method of the element), it calls the function on the event (effectively calling it in global context).
- 当您将函数直接分配给元素的事件处理程序时,
this直接在内部事件处理函数中使用是指相应的元素。这种直接的函数分配可以使用addeventListener方法或通过传统的事件注册方法来完成,如onclick. - 同样,当您
this直接在<button onclick="...this..." >元素的事件属性(如)内部使用时,它指的是该元素。 - 然而,
this通过在事件处理函数或事件属性内部调用的其他函数间接地使用解析为全局对象window。 - 当我们使用 Microsoft 的事件注册模型方法将函数附加到事件处理程序时,可以实现上述相同的行为
attachEvent。它不是将函数分配给事件处理程序(从而创建元素的函数方法),而是在事件上调用函数(在全局上下文中有效地调用它)。
I recommend to better try this in JSFiddle.
我建议在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. thisin ES6 arrow function
8. thisES6中的箭头函数
In an arrow function, thiswill behave like common variables: it will be inherited from its lexical scope. The function's this, where the arrow function is defined, will be the arrow function's this.
在箭头函数中,this将表现得像普通变量:它将从其词法范围继承。该功能的this,其中箭头函数定义,将箭头功能的this。
So, that's the same behavior as:
所以,这与以下行为相同:
(function(){}).bind(this)
See the following code:
请参阅以下代码:
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
回答by user3459110
Javascript's this
Javascript的 this
Simple function invocation
简单的函数调用
Consider the following function:
考虑以下函数:
function foo() {
console.log("bar");
console.log(this);
}
foo(); // calling the function
Note that we are running this in the normal mode, i.e. strict mode is not used.
请注意,我们在正常模式下运行它,即不使用严格模式。
When running in a browser, the value of thiswould be logged as window. This is because windowis the global variable in a web browser's scope.
在浏览器中运行时, 的值this将记录为window。这是因为window是 Web 浏览器范围内的全局变量。
If you run this same piece of code in an environment like node.js, thiswould refer to the global variable in your app.
如果您在 node.js 之类的环境中运行同一段代码,this将引用您应用程序中的全局变量。
Now if we run this in strict mode by adding the statement "use strict";to the beginning of the function declaration, thiswould no longer refer to the global variable in either of the environments. This is done to avoid confusions in strict mode. thiswould, in this case just log undefined, because that is what it is, it is not defined.
现在,如果我们通过将语句添加"use strict";到函数声明的开头以严格模式运行它,this将不再引用任一环境中的全局变量。这样做是为了避免严格模式下的混淆。this会,在这种情况下只是 log undefined,因为它就是这样,它没有定义。
In the following cases, we would see how to manipulate the value of this.
在以下情况下,我们将看到如何操作 的值this。
Calling a function on an object
在对象上调用函数
There are different ways to do this. If you have called native methods in Javascript like forEachand slice, you should already know that the thisvariable in that case refers to the Objecton which you called that function (Note that in javascript, just about everything is an Object, including Arrays and Functions). Take the following code for example.
有不同的方法可以做到这一点。如果您在 Javascript 中调用了像forEachand 之类的本地方法slice,那么您应该已经知道this在这种情况下的变量指的是Object您调用该函数的对象(请注意,在 javascript 中,几乎所有东西都是 an Object,包括Arrays 和Functions)。以下面的代码为例。
var myObj = {key: "Obj"};
myObj.logThis = function () {
// I am a method
console.log(this);
}
myObj.logThis(); // myObj is logged
If an Objectcontains a property which holds a Function, the property is called a method. This method, when called, will always have it's thisvariable set to the Objectit is associated with. This is true for both strict and non-strict modes.
如果 anObject包含持有 aFunction的属性,则该属性称为方法。此方法在调用时将始终将其this变量设置Object为与之关联的变量。对于严格和非严格模式都是如此。
Note that if a method is stored (or rather, copied) in another variable, the reference to thisis no longer preserved in the new variable. For example:
请注意,如果一个方法存储(或更确切地说,复制)在另一个变量中,则对this新变量的引用不再保留。例如:
// continuing with the previous code snippet
var myVar = myObj.logThis;
myVar();
// logs either of window/global/undefined based on mode of operation
Considering a more commonly practical scenario:
考虑一个更常见的实际场景:
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
The newkeyword
该new关键字
Consider a constructor function in Javascript:
考虑 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`
How does this work? Well, let's see what happens when we use the newkeyword.
这是如何运作的?好吧,让我们看看当我们使用new关键字时会发生什么。
- Calling the function with the
newkeyword would immediately initialize anObjectof typePerson. - The constructor of this
Objecthas its constructor set toPerson. Also, note thattypeof awalwould returnObjectonly. - This new
Objectwould be assigned the prototype ofPerson.prototype. This means that any method or property in thePersonprototype would be available to all instances ofPerson, includingawal. - The function
Personitself is now invoked;thisbeing a reference to the newly constructed objectawal.
- 使用
new关键字调用函数将立即初始化Object类型Person。 - this
Object的构造函数将其构造函数设置为Person。另外,请注意,typeof awal只会返回Object。 - 这个新的
Object将被分配的原型Person.prototype。这意味着Person原型中的任何方法或属性都可用于 的所有实例Person,包括awal. Person现在调用函数本身;this作为对新构造对象的引用awal。
Pretty straightforward, eh?
很简单吧?
Note that the official ECMAScript spec nowhere states that such types of functions are actual constructorfunctions. They are just normal functions, and newcan be used on any function. It's just that we use them as such, and so we call them as such only.
请注意,官方 ECMAScript 规范没有说明此类函数是实际constructor函数。它们只是普通函数,new可以用于任何函数。只是我们这样使用它们,所以我们只这样称呼它们。
Calling functions on Functions: calland apply
在函数上调用函数:call和apply
So yeah, since functions are also Objects(and in-fact first class variables in Javascript), even functions have methods which are... well, functions themselves.
所以是的,因为functions 也是Objects(实际上是 Javascript 中的第一类变量),即使函数也有方法......好吧,函数本身。
All functions inherit from the global Function, and two of its many methods are calland apply, and both can be used to manipulate the value of thisin the function on which they are called.
所有函数都继承自 global Function,它的许多方法中有两个是calland apply,两者都可用于操作this调用它们的函数中的值。
function foo () { console.log (this, arguments); }
var thisArg = {myObj: "is cool"};
foo.call(thisArg, 1, 2, 3);
This is a typical example of using call. It basically takes the first parameter and sets thisin the function fooas a reference to thisArg. All other parameters passed to callis passed to the function fooas arguments.
So the above code will log {myObj: "is cool"}, [1, 2, 3]in the console. Pretty nice way to change the value of thisin any function.
这是使用call. 它基本上采用第一个参数并this在函数中设置foo为对thisArg. 传递给的所有其他参数call都foo作为参数传递给函数。
所以上面的代码会登录{myObj: "is cool"}, [1, 2, 3]到控制台。改变this任何函数中的值的好方法。
applyis almost the same as callaccept that it takes only two parameters: thisArgand an array which contains the arguments to be passed to the function. So the above callcall can be translated to applylike this:
apply几乎与callaccept相同,它只需要两个参数:thisArg一个包含要传递给函数的参数的数组。所以上面的call调用可以翻译成apply这样:
foo.apply(thisArg, [1,2,3])
Note that calland applycan override the value of thisset by dot method invocation we discussed in the second bullet.
Simple enough :)
请注意,callandapply可以覆盖this我们在第二个项目符号中讨论的点方法调用设置的值。足够简单:)
Presenting.... bind!
介绍…… bind!
bindis a brother of calland apply. It is also a method inherited by all functions from the global Functionconstructor in Javascript. The difference between bindand call/applyis that both calland applywill actually invoke the function. bind, on the other hand, returns a new function with the thisArgand argumentspre-set. Let's take an example to better understand this:
bind是calland的兄弟apply。它也是FunctionJavascript 中所有函数从全局构造函数继承的方法。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]`
See the difference between the three? It is subtle, but they are used differently. Like calland apply, bindwill also over-ride the value of thisset by dot-method invocation.
看到三者的区别了吗?这很微妙,但它们的用法不同。像calland一样apply,bind也会覆盖this通过点方法调用设置的值。
Also note that neither of these three functions do any change to the original function. calland applywould return the value from freshly constructed functions while bindwill return the freshly constructed function itself, ready to be called.
另请注意,这三个函数都不会对原始函数进行任何更改。call并且apply会从新构造的函数返回值,同时bind会返回新构造的函数本身,准备被调用。
Extra stuff, copy this
额外的东西,复制这个
Sometimes, you don't like the fact that thischanges with scope, especially nested scope. Take a look at the following example.
有时,您不喜欢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"
});
}
};
In the above code, we see that the value of thischanged with the nested scope, but we wanted the value of thisfrom the original scope. So we 'copied' thisto thatand used the copy instead of this. Clever, eh?
在上面的代码中,我们看到 的值this随着嵌套范围的变化而变化,但我们想要this来自原始范围的值。所以我们“复制”this到that并使用了副本而不是this. 聪明,嗯?
Index:
指数:
- What is held in
thisby default? - What if we call the function as a method with Object-dot notation?
- What if we use the
newkeyword? - How do we manipulate
thiswithcallandapply? - Using
bind. - Copying
thisto solve nested-scope issues.
this默认保留什么?- 如果我们使用 Object-dot 符号将函数作为方法调用会怎样?
- 如果我们使用
new关键字呢? - 我们如何处理
this与call和apply? - 使用
bind. - 复制
this以解决嵌套范围问题。
回答by arunjitsingh
"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". OOP 101 teaches that "this" is only applicable to instancesof an object. Therefore, every-time a function executes, a new "instance" of that function has a new meaning of "this".
“这个”是关于范围的。每个函数都有自己的作用域,而且由于 JS 中的一切都是对象,因此即使是函数也可以使用“this”将一些值存储到自身中。OOP 101 教导“this”仅适用于对象的实例。因此,每次执行一个函数时,该函数的一个新“实例”具有“this”的新含义。
Most people get confused when they try to use "this" inside of anonymous closure functions like:
大多数人在尝试在匿名闭包函数中使用“this”时会感到困惑,例如:
(function(value) {
this.value = value;
$('.some-elements').each(function(elt){
elt.innerHTML = this.value; // uh oh!! possibly undefined
});
})(2);
So here, inside each(), "this" doesn't hold the "value" that you expect it to (from
所以在这里,在 each() 中,“this”不包含您期望的“值”(来自
this.value = value;它上面)。因此,为了克服这个(无双关语)问题,开发人员可以:
(function(value) {
var self = this; // small change
self.value = value;
$('.some-elements').each(function(elt){
elt.innerHTML = self.value; // phew!! == 2
});
})(2);
Try it out; you'll begin to like this pattern of programming
试试看; 你会开始喜欢这种编程模式
回答by Seph
thisin JavaScript always refers to the 'owner' of the function that is being executed.
this在 JavaScript 中总是指正在执行的函数的“所有者” 。
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;
element.onclick = someKindOfFunction;
thiswould refer to the element object. But be careful, a lot of people make this mistake.
this将引用元素对象。但是要小心,很多人都会犯这个错误。
<element onclick="someKindOfFunction()">
<element onclick="someKindOfFunction()">
In the latter case, you merely reference the function, not hand it over to the element. Therefore, thiswill refer to the window object.
在后一种情况下,您只是引用函数,而不是将其交给元素。因此,this会引用window对象。
回答by carlodurso
Since this thread has bumped up, I have compiled few points for readers new to thistopic.
由于此线程已增加,因此我为不熟悉该this主题的读者整理了一些要点。
How is the value of thisdetermined?
的价值是如何this确定的?
We use this similar to the way we use pronouns in natural languages like English: “John is running fast because heis trying to catch the train.” Instead we could have written “… Johnis trying to catch the train”.
我们使用这种方式类似于我们在英语等自然语言中使用代词的方式:“约翰跑得很快,因为他想赶火车。” 相反,我们可以写成“……约翰正试图赶火车”。
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);
}
}
thisis not assigned a valueuntil an object invokes the function where it is defined. In the global scope, all global variables and functions are defined on the windowobject. Therefore, thisin a global function refers to (and has the value of) the global windowobject.
this在对象调用定义它的函数之前,不会为其分配值。在全局作用域中,所有的全局变量和函数都定义在window对象上。因此,this在全局函数中引用(并具有值)全局window对象。
When use strict, thisin global and in anonymous functions that are not bound to any object holds a value of undefined.
当use strict,this在未绑定到任何对象的全局和匿名函数中的值为undefined。
The thiskeyword is most misunderstoodwhen: 1) we borrow a method that uses this, 2) we assign a method that uses thisto a variable, 3) a function that uses thisis passed as a callback function, and 4) thisis used inside a closure — an inner function. (2)
在以下情况下,this关键字最容易被误解:1) 我们借用了一个使用 的方法this,2) 我们将一个使用了的方法分配给了this一个变量,3) 一个使用的函数this作为回调函数传递,以及 4)this在闭包中使用——一个内部函数。(2)


What holds the future
什么把握未来
Defined in ECMA Script 6, arrow-functions adopt the thisbinding from the
enclosing (function or global) scope.
在ECMA Script 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!
While arrow-functions provide an alternative to using bind(), it's important to note that they essentially are disabling the traditional thismechanism in favor of more widely understood lexical scoping. (1)
虽然箭头函数提供了 using 的替代方法bind(),但重要的是要注意,它们本质上是禁用传统this机制,以支持更广泛理解的词法范围。(1)
References:
参考:
- this & Object Prototypes, by Kyle Simpson. ? 2014 Getify Solutions.
- javascriptissexy.com - http://goo.gl/pvl0GX
- Angus Croll - http://goo.gl/Z2RacU
- this & Object Prototypes,作者:Kyle Simpson。? 2014 年 Getify 解决方案。
- javascriptissexy.com - http://goo.gl/pvl0GX
- 安格斯·克罗尔 - http://goo.gl/Z2RacU
回答by blockhead
Every execution contextin javascript has a thisparameter that is set by:
javascript 中的每个执行上下文都有一个this参数,该参数由以下内容设置:
- How the function is called (including as an object method, use of calland apply, use of new)
- Use of bind
- Lexically for arrow functions (they adopt the thisof their outer execution context)
- Whether the code is in strict or non-strict mode
- Whether the code was invoked using
eval
- 如何调用函数(包括作为对象方法、使用call和apply、使用new)
- 绑定的使用
- 词法上的箭头函数(它们采用其外部执行上下文的this)
- 代码处于严格模式还是非严格模式
- 是否使用调用代码
eval
You can set the value of thisusing func.call, func.applyor func.bind.
您可以使用,或设置this的值。func.callfunc.applyfunc.bind
By default, and what confuses most beginners, when a listener is called after an event is raised on a DOM element, the thisvalue of the function is the DOM element.
默认情况下,让大多数初学者感到困惑的是,当在 DOM 元素上引发事件后调用侦听器时,函数的this值是 DOM 元素。
jQuery makes this trivial to change with jQuery.proxy.
jQuery 使用 jQuery.proxy 使这一点变得微不足道。
回答by zangw
Hereis one good source of thisin JavaScript.
这是thisin 的一个很好的来源JavaScript。
Here is the summary:
这是摘要:
global this
In a browser, at the global scope,
thisis thewindowobject<script type="text/javascript"> console.log(this === window); // true var foo = "bar"; console.log(this.foo); // "bar" console.log(window.foo); // "bar"In
nodeusing the repl,thisis the top namespace. You can refer to it asglobal.>this { ArrayBuffer: [Function: ArrayBuffer], Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 }, Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 }, ... >global === this trueIn
nodeexecuting from a script,thisat the global scope starts as an empty object. It is not the same asglobal\test.js console.log(this); \ {} console.log(this === global); \ faslefunction this
全球这个
在浏览器中,在全局范围内,
this是window对象<script type="text/javascript"> console.log(this === window); // true var foo = "bar"; console.log(this.foo); // "bar" console.log(window.foo); // "bar"在
node使用 repl 时,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功能这个
Except in the case of DOM event handlers or when a thisArgis provided (see further down), both in node and in a browser using thisin a function that is not called with newreferences the global scope…
除了在 DOM 事件处理程序的情况下或thisArg提供a 的情况下(见下文),无论是在节点中还是在浏览器中使用this的函数都没有被new引用全局范围......
<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 thiswill be undefined
如果您使用use strict;,在这种情况下this将是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 newthe thiswill be a new context, it will not reference the global this.
如果你调用一个函数new的this将是一个新的环境,也不会引用全局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 prototypeproperty, which is something you can assign values to. When you create an instance by calling your function with newyou get access to the values you assigned to the prototypeproperty. You access those values using this.
您创建的函数成为函数对象。它们会自动获得一个特殊的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"
It is usually a mistake to assign arraysor objectson the prototype. If you want instances to each have their own arrays, create them in the function, not the prototype.
它通常是一个错误的分配数组或对象上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 thisin any function on an object to refer to other properties on that object. This is not the same as an instance created with new.
您可以this在对象上的任何函数中使用来引用该对象上的其他属性。这与使用new.
var obj = {
foo: "bar",
logFoo: function () {
console.log(this.foo);
}
};
obj.logFoo(); //logs "bar"
- DOM event this
- DOM 事件这个
In an HTML DOM event handler, thisis always a reference to the DOM element the event was attached to
在 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();
Unless you bindthe context
除非你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 this
- HTML 这个
Inside HTML attributes in which you can put JavaScript, thisis a reference to the element.
在可以放置 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
- 评价这个
You can use evalto access this.
您可以使用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();
- with this
- 有了这个
You can use withto add thisto the current scope to read and write to values on thiswithout referring to thisexplicitly.
您可以使用with添加this到当前范围来读取和写入值,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 这个
the jQuery will in many places have thisrefer to a DOM element.
jQuery 会在很多地方this引用一个 DOM 元素。
<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>
回答by Arman McHitarian
Daniel, awesome explanation! A couple of words on this and good list of thisexecution context pointer in case of event handlers.
丹尼尔,很棒的解释!this在事件处理程序的情况下,关于这个和执行上下文指针的好列表的几个词。
In two words, thisin 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.
简而言之,this在 JavaScript 中指向当前函数从谁(或从谁的执行上下文)运行的对象,并且它始终是只读的,无论如何您都无法设置它(这种尝试最终会以“无效的左手作业中的消息。
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 :)
对于事件处理程序:内联事件处理程序,例如<element onclick="foo">,覆盖之前和之前附加的任何其他处理程序,所以要小心,最好完全远离内联事件委托。还要感谢 Zara Alaverdyan,她通过不同意见的辩论启发了我列出了这份示例清单 :)
el.onclick = foo; // in the foo - objel.onclick = function () {this.style.color = '#fff';} // objel.onclick = function() {doSomething();} // In the doSomething - Windowel.addEventListener('click',foo,false) // in the foo - objel.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)">
el.onclick = foo; // in the foo - objel.onclick = function () {this.style.color = '#fff';} // objel.onclick = function() {doSomething();} // In the doSomething - Windowel.addEventListener('click',foo,false) // in the foo - objel.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)">
回答by Dmitri Pavlutin
Probably the most detailed and comprehensive article on thisis the following:
可能最详细和最全面的文章this如下:
Gentle explanation of 'this' keyword in JavaScript
The idea behind thisis to understand that the function invocation types have the significant importance on setting thisvalue.
背后的想法this是理解函数调用类型对设置this值具有重要意义。
When having troubles identifying this, do notask yourself:
当识别困难时this,不要问自己:
Where is
thistaken from?
this取自哪里?
but doask yourself:
但不要问自己:
How is the function invoked?
函数是如何调用的?
For an arrow function (special case of context transparency) ask yourself:
对于箭头函数(上下文透明的特殊情况)问问自己:
What value has
thiswhere the arrow function is defined?
定义
this箭头函数的地方有什么值?
This mindset is correct when dealing with thisand will save you from headache.
这种心态在处理时是正确的this,可以使您免于头痛。

