我注意到,似乎没有明确解释this
关键字是什么以及如何在Stack Overflow网站上的JavaScript中正确(不正确地)使用它。
我目睹了它的一些非常奇怪的行为,并且无法理解为什么会发生它。
此
如何工作以及何时应使用?
我建议阅读迈克·韦斯特(Mike West)的文章 JavaScript的作用域(镜像)。这是对this
和JavaScript范围链的概念的出色而友好的介绍。
一旦您开始习惯于this
,规则实际上非常简单。 ECMAScript 5.1标准定义了this
:
§11.1.1
this
关键字
this
关键字的计算结果为当前执行上下文的ThisBinding的值
ThisBinding是JavaScript解释器在评估JavaScript代码时所维护的东西,例如特殊的CPU寄存器,其中包含对对象的引用。每当在以下三种情况之一中建立执行上下文时,解释器都会更新ThisBinding:
在最高级别(例如,直接在内:
在初始全局执行上下文中评估代码时,ThisBinding设置为全局对象window
(§10.4.1.1)。
…通过直接调用eval()
来保持此绑定不变;它与调用执行上下文的ThisBinding相同(§10.4 .2 (2)(a))。
…如果不是通过直接调用eval()
,则此Binding设置为全局对象,就像在初始全局执行上下文中执行 (§10.4.2(1))。
§15.1.2.1.1定义了直接调用eval()
的含义。基本上,eval(...)
是直接调用,而类似(0,eval)(...)
或varindirectEval=eval;indirectEval(...);
是对eval()
的间接调用。请参阅 chuckj的答案对 ,eval)('this')与eval('this')在JavaScript中?和德米特里·索什尼科夫的ECMA-262-5详细信息。第2章。严格模式。有关何时可以使用间接的eval()
调用。
在调用函数时会发生这种情况。如果在对象上调用函数,例如在obj.myMethod()
或等效的obj["myMethod"]()
中调用,则将此绑定设置为对象(在示例中为obj
; §13.2。 1 )。在大多数其他情况下,ThisBinding设置为全局对象(§10.4。 3 )。
之所以写"在大多数情况下",是因为有八个ECMAScript 5内置函数可以在参数列表中指定ThisBinding。这些特殊功能采用了所谓的thisArg
,在调用该功能时,它会成为ThisBinding(第10.4.3 )。
这些特殊的内置函数是:
Function.prototype.apply(thisArg,argArray)
Function.prototype.call(thisArg[,arg1[,arg2,...]])
Function.prototype.bind(thisArg[,arg1[,arg2,...]])
Array.prototype.every(callbackfn[,thisArg])
Array.prototype.some(callbackfn[,thisArg])
Array.prototype.forEach(callbackfn[,thisArg])
Array.prototype.map(callbackfn[,thisArg])
Array.prototype.filter(callbackfn[,thisArg])
对于Function.prototype
函数,它们是在函数对象上调用的,而不是将ThisBinding设置为函数对象,而是将ThisBinding设置为thisArg
。
如果使用Array.prototype
函数,则在执行上下文中调用给定的callbackfn
,如果执行上下文中ThisBinding设置为thisArg
提供;否则,转到全局对象。
这些是普通JavaScript的规则。当您开始使用JavaScript库(例如jQuery)时,您可能会发现某些库函数会操纵this
的值。这些JavaScript库的开发人员这样做是因为它倾向于支持最常见的用例,并且该库的用户通常会发现此行为更加方便。当将引用this
的回调函数传递给库函数时,您应参考文档以确保有关调用该函数时this
的值的任何保证。
如果您想知道JavaScript库如何处理this
的值,则该库只是使用接受thisArg
的内置JavaScript函数之一。您也可以使用回调函数和thisArg
:
我还没有提到一种特殊情况。通过new
运算符构造新对象时,JavaScript解释器将创建一个新的空对象,设置一些内部属性,然后在新对象上调用构造函数。因此,当在构造函数上下文中调用函数时,this
的值是解释器创建的新对象:
箭头功能(在ECMA6中引入)更改this
的范围。请参阅现有的规范问题,箭头函数与函数声明/表达式:它们是否等效/可互换?以获取更多信息。简而言之:
箭头函数没有自己的
this
....绑定。相反,这些标识符像任何其他变量一样在词法范围内解析。这意味着在箭头函数内部,this
...是指在定义箭头函数的环境中this
的值。
要显示答案,请将鼠标悬停在浅黄色框上。
标记行上的this
的值是什么?为什么?
window
—在初始的全局执行上下文中评估标记的行。
执行obj.staticFunction()
时,标记行上的this
的值是什么?为什么?
obj
—在对象上调用函数时,ThisBinding设置为该对象。
标记行上的this
的值是什么?为什么?
窗口
在此示例中,JavaScript解释器输入了功能代码,但是由于未在对象上调用
myFun
/obj.myMethod
,因此ThisBinding设置为window
。这与Python不同,在Python中,访问方法(
obj.myMethod
)创建绑定方法对象。
标记行上的this
的值是什么?为什么?
窗口
这很棘手。在评估评估代码时,
this
是obj
。但是,在评估代码中,未在对象上调用myFun
,因此此绑定被设置为window
进行调用。
标记行上的this
的值是什么?为什么?
obj
myFun.call(obj);
行正在调用特殊的内置函数Function.prototype.call()
,该函数接受thisArg
作为第一个参数。
与其他语言相比,this
关键字在JavaScript中的行为有所不同。在面向对象的语言中,this
关键字引用该类的当前实例。在JavaScript中,this
的值由函数( context.function()
)的调用上下文及其调用位置确定。
1。在全局环境下使用
在全局上下文中使用this
时,它将绑定到全局对象(浏览器中的window
)
document.write(this); //[object Window]
当在全局上下文中定义的函数内使用this
时,this
仍绑定到全局对象,因为该函数实际上是全局上下文的方法。 / p>
function f1()
{
return this;
}
document.write(f1()); //[object Window]
在f1
之上已成为全局对象的方法。因此,我们也可以在window
对象上调用它,如下所示:
function f()
{
return this;
}
document.write(window.f()); //[object Window]
2。在内部对象方法中使用时
在对象方法内使用this
关键字时,this
绑定到"立即"封闭对象。
var obj = {
name: "obj",
f: function () {
return this + ":" + this.name;
}
};
document.write(obj.f()); //[object Object]:obj
在上面,我将单词立即用双引号引起来。要指出的是,如果将对象嵌套在另一个对象中,则this
绑定到直接父对象。
var obj = {
name: "obj1",
nestedobj: {
name:"nestedobj",
f: function () {
return this + ":" + this.name;
}
}
}
document.write(obj.nestedobj.f()); //[object Object]:nestedobj
即使您将函数显式添加为对象的方法,它仍然遵循上述规则,也就是说,this
仍指向直接父对象。
var obj1 = {
name: "obj1",
}
function returnName() {
return this + ":" + this.name;
}
obj1.f = returnName; //add method to object
document.write(obj1.f()); //[object Object]:obj1
3。调用无上下文功能时
当您在没有任何上下文的情况下(即不在任何对象上)使用内部函数中的this
时,它将绑定到全局对象(浏览器中的window
)(即使该函数是在对象内部定义的。)
var context = "global";
var obj = {
context: "object",
method: function () {
function f() {
var context = "function";
return this + ":" +this.context;
};
return f(); //invoked without context
}
};
document.write(obj.method()); //[object Window]:global
尝试使用功能
我们也可以尝试以上功能。但是有一些区别。
this
将成员添加到函数中。指定它们。new
运算符创建其实例。下面,我通过上面的Object和this
尝试了所有操作,但是首先创建函数,而不是直接编写对象。
/*********************************************************************
1. When you add variable to the function using this keyword, it
gets added to the function prototype, thus allowing all function
instances to have their own copy of the variables added.
*********************************************************************/
function functionDef()
{
this.name = "ObjDefinition";
this.getName = function(){
return this+":"+this.name;
}
}
obj1 = new functionDef();
document.write(obj1.getName() + "<br />"); //[object Object]:ObjDefinition
/*********************************************************************
2. Members explicitly added to the function protorype also behave
as above: all function instances have their own copy of the
variable added.
*********************************************************************/
functionDef.prototype.version = 1;
functionDef.prototype.getVersion = function(){
return "v"+this.version; //see how this.version refers to the
//version variable added through
//prototype
}
document.write(obj1.getVersion() + "<br />"); //v1
/*********************************************************************
3. Illustrating that the function variables added by both above
ways have their own copies across function instances
*********************************************************************/
functionDef.prototype.incrementVersion = function(){
this.version = this.version + 1;
}
var obj2 = new functionDef();
document.write(obj2.getVersion() + "<br />"); //v1
obj2.incrementVersion(); //incrementing version in obj2
//does not affect obj1 version
document.write(obj2.getVersion() + "<br />"); //v2
document.write(obj1.getVersion() + "<br />"); //v1
/*********************************************************************
4. `this` keyword refers to the immediate parent object. If you
nest the object through function prototype, then `this` inside
object refers to the nested object not the function instance
*********************************************************************/
functionDef.prototype.nestedObj = { name: 'nestedObj',
getName1 : function(){
return this+":"+this.name;
}
};
document.write(obj2.nestedObj.getName1() + "<br />"); //[object Object]:nestedObj
/*********************************************************************
5. If the method is on an object's prototype chain, `this` refers
to the object the method was called on, as if the method was on
the object.
*********************************************************************/
var ProtoObj = { fun: function () { return this.a } };
var obj3 = Object.create(ProtoObj); //creating an object setting ProtoObj
//as its prototype
obj3.a = 999; //adding instance member to obj3
document.write(obj3.fun()+"<br />");//999
//calling obj3.fun() makes
//ProtoObj.fun() to access obj3.a as
//if fun() is defined on obj3
4。在构造函数内部使用时。
当函数用作构造函数时(即使用new
关键字调用时),函数体内的this
指向正在构造的新对象。< / p>
var myname = "global context";
function SimpleFun()
{
this.myname = "simple function";
}
var obj1 = new SimpleFun(); //adds myname to obj1
//1. `new` causes `this` inside the SimpleFun() to point to the
// object being constructed thus adding any member
// created inside SimipleFun() using this.membername to the
// object being constructed
//2. And by default `new` makes function to return newly
// constructed object if no explicit return value is specified
document.write(obj1.myname); //simple function
5。在原型链上定义的内部函数中使用时
如果该方法位于对象的原型链上,则该方法内的this
引用该方法被调用的对象,就像该方法是在对象上定义的一样。
var ProtoObj = {
fun: function () {
return this.a;
}
};
//Object.create() creates object with ProtoObj as its
//prototype and assigns it to obj3, thus making fun()
//to be the method on its prototype chain
var obj3 = Object.create(ProtoObj);
obj3.a = 999;
document.write(obj3.fun()); //999
//Notice that fun() is defined on obj3's prototype but
//`this.a` inside fun() retrieves obj3.a
6。在call(),apply()和bind()函数中
Function.prototype
上定义的。this
的值。在调用原始函数时,它们还可以将任何参数传递给原始函数。fun.apply(obj1[,argsArray])
将obj1
设置为< code> fun()并调用fun()
并传递argsArray
的元素作为其参数。fun.call(obj1[,arg1[,arg2[,arg3[,...]]]])
-设置obj1
作为fun()
中的this
的值,并调用fun()
并传递arg1,arg2,arg3,...
作为其参数。
fun.bind(obj1[,arg1[,arg2[,arg3[,...]]]])
-返回对函数
fun
,其中this
内在fun绑定到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。事件处理程序中的this
this
就是指相应的元素。可以使用addeventListener
方法或通过传统的事件注册方法(如onclick
)来完成这种直接功能分配。
)内部使用this
时,它会是指元素。this
会解析为全局对象window
。attachEvent
将函数附加到事件处理程序时,可以实现上述相同的行为。它没有将功能分配给事件处理程序(因而没有将其分配为元素的功能方法),而是对事件进行了调用(在全局上下文中有效地进行了调用)。我建议最好在 JSFiddle 。
<script>
function clickedMe() {
alert(this + " : " + this.tagName + " : " + this.id);
}
document.getElementById("button1").addEventListener("click", clickedMe, false);
document.getElementById("button2").onclick = clickedMe;
document.getElementById("button5").attachEvent('onclick', clickedMe);
</script>
<h3>Using `this` "directly" inside event handler or event property</h3>
<button id="button1">click() "assigned" using addEventListner() </button><br />
<button id="button2">click() "assigned" using click() </button><br />
<button id="button3" onclick="alert(this+ ' : ' + this.tagName + ' : ' + this.id);">used `this` directly in click event property</button>
<h3>Using `this` "indirectly" inside event handler or event property</h3>
<button onclick="alert((function(){return this + ' : ' + this.tagName + ' : ' + this.id;})());">`this` used indirectly, inside function <br /> defined & called inside event property</button><br />
<button id="button4" onclick="clickedMe()">`this` used indirectly, inside function <br /> called inside event property</button> <br />
IE only: <button id="button5">click() "attached" using attachEvent() </button>
8。 ES6箭头功能中的this
在箭头函数中,this
的行为类似于常见变量:它将从其词法范围继承。该函数的this
(其中定义了箭头功能)将是箭头函数的this
。
所以,这与以下行为相同:
(function(){}).bind(this)
请参见以下代码:
const globalArrowFunction = () => {
return this;
};
console.log(globalArrowFunction()); //window
const contextObject = {
method1: () => {return this},
method2: function(){
return () => {return this};
}
};
console.log(contextObject.method1()); //window
const contextLessFunction = contextObject.method1;
console.log(contextLessFunction()); //window
console.log(contextObject.method2()()) //contextObject
const innerArrowFunction = contextObject.method2();
console.log(innerArrowFunction()); //contextObject
this
请考虑以下功能:
function foo() {
console.log("bar");
console.log(this);
}
foo(); // calling the function
请注意,我们正在正常模式下运行此程序,即未使用严格模式。
在浏览器中运行时,this
的值将记录为window
。这是因为window
是Web浏览器范围内的全局变量。
如果您在诸如node.js之类的环境中运行同一段代码,则this
将引用您应用程序中的全局变量。
现在,如果我们通过在函数声明的开头添加语句"usestrict";
在严格模式下运行此命令,则this
将不再引用全局变量在任何一个环境中都是变量。这样做是为了避免在严格模式下造成混淆。在这种情况下,this
只需记录undefined
,因为它就是它,没有定义。
在以下情况下,我们将看到如何操纵this
的值。
有不同的方法可以做到这一点。如果您已经用Javascript调用了诸如forEach
和slice
之类的本机方法,那么您应该已经知道在这种情况下,this
变量引用了您在其上调用了该函数的对象(请注意,在javascript中,几乎所有对象都是一个
<对象>
对象>,包括
<对象>
数组
对象>和
<对象>
功能
对象> s)。以下面的代码为例。
var myObj = {key: "Obj"};
myObj.logThis = function () {
// I am a method
console.log(this);
}
myObj.logThis(); // myObj is logged
如果Object
包含一个包含Function
的属性,则该属性称为方法。调用此方法时,始终会将其this
变量设置为与之关联的Object
。对于严格和非严格模式都是如此。
请注意,如果方法存储(或复制)在另一个变量中,则对此this
的引用不再保留在新变量中。例如:
// continuing with the previous code snippet
var myVar = myObj.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
关键字时会发生什么。
- 使用
new
关键字调用该函数将立即初始化Person
类型的Object
。
- 此
Object
的构造函数将其构造函数设置为Person
。另外,请注意,typeofawal
将仅返回Object
。
- 此新的
Object
将被分配为Person.prototype
的原型。这意味着Person
原型中的任何方法或属性都可用于Person
的所有实例,包括awal
。
-
Person
函数本身已被调用; this
是对新建对象awal
的引用。
很简单吧?
请注意,官方ECMAScript规范无处声明此类函数是实际的constructor
函数。它们只是正常功能,new
可以用于任何功能。只是我们照原样使用它们,因此我们仅如此称呼它们。
在函数上调用函数:call
和apply
是的,因为function
也是Objects
(实际上是Javascript中的第一类变量),所以即使函数也具有...自己。
所有函数均从全局Function
继承,其许多方法中的两个是call
和apply
,并且都可以用来操作this
在调用它们的函数中的值。
function foo () { console.log (this, arguments); }
var thisArg = {myObj: "is cool"};
foo.call(thisArg, 1, 2, 3);
这是使用call
的典型示例。它基本上采用第一个参数,并将函数foo
中的this
设置为对thisArg
的引用。传递给call
的所有其他参数都作为参数传递给函数foo
。
因此,以上代码将记录{myObj:"iscool"},控制台中的[1、2、3]
。在任何函数中更改this
的值的非常不错的方法。
apply
与call
几乎相同,只接受两个参数:thisArg
和一个包含要传递的参数的数组功能。因此,上述call
调用可以转换为apply
,例如:
foo.apply(thisArg, [1,2,3])
请注意,call
和apply
可以覆盖我们在第二个项目符号中讨论的点方法调用设置的this
的值。很简单:)
正在展示...... 绑定
!
bind
是call
和apply
的兄弟。它也是所有函数从Javascript的全局Function
构造函数继承的方法。 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]`
看到三个之间的区别了吗?它很微妙,但是用法不同。像call
和apply
一样,bind
也将覆盖通过点方法调用设置的this
的值。
还请注意,这三个功能均未对原始功能进行任何更改。 call
和apply
将返回新构造函数的值,而bind
将返回新构造函数本身,随时可以调用。
其他内容,请复制
有时候,您不喜欢this
随范围(尤其是嵌套范围)而变化的事实。看下面的例子。
var myObj = {
hello: function () {
return "world"
},
myMethod: function () {
// copy this, variable names are case-sensitive
var that = this;
// callbacks ftw \o/
foo.bar("args", function () {
// I want to call `hello` here
this.hello(); // error
// but `this` references to `foo` damn!
// oh wait we have a backup \o/
that.hello(); // "world"
});
}
};
在上面的代码中,我们看到this
的值随嵌套范围而变化,但是我们希望从原始范围中获得this
的值。因此,我们将this
复制到that
,并使用副本而不是this
。聪明吧?
索引:
- 默认情况下,
this
中包含什么?
- 如果我们将函数作为带有对象点表示法的方法来调用怎么办?
- 如果我们使用
new
关键字怎么办?
- 我们如何通过
call
和apply
来操纵this
?
- 使用
bind
。
- 复制
this
以解决嵌套范围的问题。
"这"与范围有关。每个函数都有自己的作用域,并且由于JS中的所有内容都是对象,所以即使一个函数也可以使用"此"将一些值存储到自身中。 OOP 101教导" this"仅适用于对象的 instances 。因此,每次执行一个函数时,该函数的新"实例"都具有" this"的新含义。
大多数人在匿名闭包函数中尝试使用" this"时会感到困惑:
(function(value) { this.value = value; $('.some-elements').each(function(elt){ elt.innerHTML = this.value; // uh oh!! possibly undefined }); })(2);
因此在这里,在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);
尝试一下;您将开始喜欢这种编程模式
自从这个话题浮出水面以来,我为this
主题的新读者提供了几点建议。
this
的值?我们使用这种方法类似于在自然语言(如英语)中使用代词的方式:"约翰跑得很快,因为 他 正试图赶上火车。"相反,我们可以写成"…… John 正试图赶上火车"。
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);
}
}
此
没有分配值,直到对象调用定义它的函数。在全局范围内,所有全局变量和函数都在window
对象上定义。因此,全局函数中的this
引用全局window
对象(并具有其值)。
在使用strict
时,在全局和未绑定到任何对象的匿名函数中,此this
的值为undefined
。
this
关键字为在以下情况下最容易被误解的:1)我们借用了一个使用this
的方法,2)我们将了一个使用this
的方法分配给了一个变量,3)a使用this
的函数作为回调函数传递,并且4)this
用于闭包内部的内部函数。 (2)
箭头功能在 ECMA脚本6 中定义,箭头功能采用this
绑定来自封闭的(函数或全局)范围。
function foo() {
// return an arrow function
return (a) => {
// `this` here is lexically inherited from `foo()`
console.log(this.a);
};
}
var obj1 = { a: 2 };
var obj2 = { a: 3 };
var bar = foo.call(obj1);
bar.call( obj2 ); // 2, not 3!
虽然箭头函数提供了使用bind()
的替代方法,但必须注意的是,它们实际上是在禁用传统的this
机制,而倾向于使用更广泛理解的词法范围界定。 (1)
参考文献:
this
始终是指正在执行的函数的"所有者"。
如果未定义任何显式所有者,则引用最高的所有者,即窗口对象。
如果我这样做了
function someKindOfFunction() {
this.style = 'foo';
}
element.onclick=someKindOfFunction;
this
将引用元素对象。但是要小心,很多人都会犯这个错误。
在后一种情况下,您仅引用函数,而不将其移交给元素。因此,this
将引用窗口对象。
每个执行上下文都有一个 this 参数,该参数的设置方式是:
评估
您可以使用func.call
,func.apply
或func.bind
设置 this 的值
默认情况下,也是最令初学者困惑的是,在DOM元素上引发事件后调用侦听器时,该函数的 this 值为DOM元素。
jQuery使用jQuery.proxy可以轻松改变这一点。
此处是
。this
中的一个很好的来源JavaScript
以下是摘要:
全局此
在浏览器中,在全局范围内,this
是window
对象
<script type="text/javascript">
console.log(this === window); // true
var foo = "bar";
console.log(this.foo); // "bar"
console.log(window.foo); // "bar"
在使用副本的node
中,this
是顶级命名空间。您可以将其称为global
。
>this
{ ArrayBuffer: [Function: ArrayBuffer],
Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
...
>global === this
true
在node
中通过脚本执行,this
在全局范围内从一个空对象开始。它与global
\\test.js
console.log(this); \\ {}
console.log(this === global); \\ fasle
此功能
在DOM事件处理程序中或在提供了thisArg
的情况下(请参见下文),在节点和浏览器中使用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>
如果使用usestrict;
,则在这种情况下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>
如果使用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
属性,您可以为其分配值。通过使用new
调用函数来创建实例时,可以访问分配给prototype
属性的值。您可以使用this
访问这些值。
function Thing() {
console.log(this.foo);
}
Thing.prototype.foo = "bar";
var thing = new Thing(); //logs "bar"
console.log(thing.foo); //logs "bar"
在prototype
上分配 arrays 或 objects 通常是一个错误。如果您希望实例各自具有自己的数组,请在函数(而不是原型)中创建它们。
function Thing() {
this.things = [];
}
var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing1.things); //logs ["foo"]
console.log(thing2.things); //logs []
您可以在对象的任何函数中使用this
来引用该对象的其他属性。这与使用new
创建的实例不同。
var obj = {
foo: "bar",
logFoo: function () {
console.log(this.foo);
}
};
obj.logFoo(); //logs "bar"
在HTML DOM事件处理程序中,this
始终是对该事件附加到
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();
除非您绑定
上下文
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();
在其中可以放置JavaScript的HTML属性中,this
是对该元素的引用。
<div id="foo" onclick="console.log(this);"></div>
<script type="text/javascript">
document.getElementById("foo").click(); //logs <div id="foo"...
</script>
您可以使用eval
来访问this
。
function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
eval("console.log(this.foo)"); //logs "bar"
}
var thing = new Thing();
thing.logFoo();
您可以使用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
引用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>
丹尼尔,真棒!在事件处理程序的情况下,这两个单词以及this
执行上下文指针的良好列表。
用两个词,JavaScript中的this
指向运行当前函数的对象(或从其执行上下文)运行的对象,并且该对象始终是只读的,您无论如何都无法设置它(例如尝试将以"分配中的左侧无效"消息结束。
对于事件处理程序:内联事件处理程序(例如
)会覆盖之前和之前附加的所有其他处理程序,因此请当心,最好不要参加内联事件委托。还要感谢Zara Alaverdyan,他通过一次持异议的辩论启发了我列出了这些示例:)
el.onclick=foo;//在foo中-obj
el.onclick=function(){this.style.color='#fff';}//obj
el.onclick=function(){doSomething();}//在doSomething-窗口中
el.addEventListener('click',foo,false)//在foo中-obj
el.attachEvent('onclick,function(){//此}')//窗口,所有均符合IE:)
//obj
//在foo-窗口中,但是您可以
在JavaScript中如何解释" this" 关键字存在很多困惑。希望本文能使所有这些人一劳永逸。还有更多。请仔细阅读整篇文章。请注意,本文太长了。
无论使用哪种上下文,"此" 始终在Javascript中引用"当前对象" 。但是,"当前对象" 的不同取决于上下文。 上下文可能恰好是以下6个变量中的 1个:
以下逐个描述了每种上下文:
全局上下文(即,在所有函数之外):
在所有函数之外(即,在全局上下文中)"当前对象" (因此" this" 的值)始终是浏览器的"窗口" 对象。
在直接"无界函数"调用中:
在直接"无界函数"调用中,调用函数调用的对象变为"当前对象" (以及" this" 的值)。如果在没有显式当前对象的情况下调用函数,则当前对象是"窗口" 对象(用于非严格模式)或< strong> undefined (用于严格模式)。在 Global Context 中定义的任何函数(或变量)都将自动成为" window" 对象的属性。例如,假设在Global Context中将函数定义为
< pre>它成为窗口对象的属性,就像您已将其定义为
function UserDefinedFunction(){
alert(this)
}
在"非严格模式"中,调用/调用此直接通过" UserDefinedFunction()" 函数将自动调用/调用为" window.UserDefinedFunction()" ,将" window" 设置为< " UserDefinedFunction" 中的strong>"当前对象" (以及" this" 的值)。将导致在"非严格模式"下调用此功能在以下
window.UserDefinedFunction=function(){
alert(this)
}
中,在"严格模式"下,直接通过" UserDefinedFunction()" 调用/调用该函数将" NOT" < / strong>自动将其作为" window.UserDefinedFunction()" 调用/调用。因此,
UserDefinedFunction() // displays [object Window] as it automatically gets invoked as window.UserDefinedFunction()
但是,使用窗口对象显式调用该功能将导致以下结果
UserDefinedFunction() // displays undefined
让我们看看另一个例子。请看下面的代码
window.UserDefinedFunction() // "always displays [object Window] irrespective of mode."
在上面的示例中,我们看到当通过 o1 调用" UserDefinedFunction" 时, "此" 的值为 o1 ,并显示其属性的值" a" 和" b" 。 " c" 和" d" 的值显示为 undefined ,因为 o1 未定义这些属性< / p>
类似地,当通过 o2 调用" UserDefinedFunction" 时,"此" 的值为 o2 及其属性值" c" 和" d" 。将显示" a" 和" b " 显示为未定义,因为 o2 未定义这些属性。
内部间接"非绑定函数"调用 / em> :
通过 functionName.call 调用"非绑定函数" 时 functionName.apply ,"当前对象" (因此" this" 的值)设置为"此" 参数(第一个参数)的值传递给通话/应用。以下代码演示了相同的情况。
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
上面的代码清楚地表明,可以通过 call / apply <更改任何" non bound function"的" this"值 strong> 。另外,如果 " this" 参数未明确传递给 通话/应用, "当前对象" (因此," this"的值")在非严格模式下设置为 "窗口" ,在严格模式下设置为 "未定义" 。 更改任何">
内部"绑定函数"调用(即已通过调用 functionName.bind 绑定的函数):
绑定函数是"此" 值已固定的函数。下面的代码演示了" this" 在绑定函数的情况下的工作方式
function UserDefinedFunction()
{
alert(this.a + "," + this.b + "," + this.c + "," + this.d)
}
var o1={
a:1,
b:2,
f:UserDefinedFunction
}
var o2={
c:3,
d:4,
f:UserDefinedFunction
}
UserDefinedFunction.call(o1) // Shall display 1,2,undefined,undefined
UserDefinedFunction.apply(o1) // Shall display 1,2,undefined,undefined
UserDefinedFunction.call(o2) // Shall display undefined,undefined,3,4
UserDefinedFunction.apply(o2) // Shall display undefined,undefined,3,4
o1.f.call(o2) // Shall display undefined,undefined,3,4
o1.f.apply(o2) // Shall display undefined,undefined,3,4
o2.f.call(o1) // Shall display 1,2,undefined,undefined
o2.f.apply(o1) // Shall display 1,2,undefined,undefined
如上面的代码中所述,不能通过调用/应用更改任何"绑定功能" 。另外,如果未明确传递" this" 参数进行绑定,则"当前对象" (因此" this" 的值)在非严格模式下设置为"窗口" ,在严格模式下设置为"未定义" 。还有一件事。绑定已经绑定的函数不会更改" this" 的值。它仍然设置为第一个绑定函数设置的值。
通过"新建"创建对象:
在构造函数中,"当前对象" (因此值"此" 的""引用当前通过"新建" 创建的对象,而与函数的绑定状态无关。但是,如果构造函数是绑定函数,则应使用为绑定函数设置的预定义参数集来调用它。
内部内联DOM事件处理程序:
请查看以下HTML代码段
function UserDefinedFunction()
{
alert(this.a + "," + this.b + "," + this.c + "," + this.d)
}
var o1={
a:1,
b:2,
f:UserDefinedFunction,
bf:null
}
var o2={
c:3,
d:4,
f:UserDefinedFunction,
bf:null
}
var bound1=UserDefinedFunction.bind(o1); // permanantly fixes "this" value of function "bound1" to Object o1
bound1() // Shall display 1,2,undefined,undefined
var bound2=UserDefinedFunction.bind(o2); // permanantly fixes "this" value of function "bound2" to Object o2
bound2() // Shall display undefined,undefined,3,4
var bound3=o1.f.bind(o2); // permanantly fixes "this" value of function "bound3" to Object o2
bound3() // Shall display undefined,undefined,3,4
var bound4=o2.f.bind(o1); // permanantly fixes "this" value of function "bound4" to Object o1
bound4() // Shall display 1,2,undefined,undefined
o1.bf=UserDefinedFunction.bind(o2) // permanantly fixes "this" value of function "o1.bf" to Object o2
o1.bf() // Shall display undefined,undefined,3,4
o2.bf=UserDefinedFunction.bind(o1) // permanantly fixes "this" value of function "o2.bf" to Object o1
o2.bf() // Shall display 1,2,undefined,undefined
bound1.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
bound1.apply(o2) // Shall still display 1,2,undefined,undefined. "apply" cannot alter the value of "this" for bound function
o2.bf.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
o2.bf.apply(o2) // Shall still display 1,2,undefined,undefined."apply" cannot alter the value of "this" for bound function
上面示例中的>" this" 分别指" button"元素和" div"元素。
在第一个示例中,当按钮的字体颜色设置为白色时在第二个示例中,当点击" div" 元素时,它将调用 OnDivClick 函数,其第二个参数引用被单击的div。元件。但是,OnDivClick中的"此" 的值不能引用单击的 div 元素。应分别在非严格和严格模式中将其设置为"窗口对象" 或"未定义" (如果 OnDivClick 是未绑定功能)或设置为预定义的Bound值(如果 OnDivClick 是绑定功能)
以下总结了整篇文章
在全局上下文中"此" 始终引用"窗口" 对象
每当调用一个函数时,都会在一个对象("当前对象" )的上下文中调用它。如果未明确提供当前对象,则当前对象是非严格模式中的"窗口对象" 。和默认情况下在严格模式下的"未定义" 。
无界函数中" this" 的值是在调用该函数的上下文中对对象的引用("当前对象" )
无界函数中" this" 的值可以通过该函数的调用和 apply 方法来覆盖。
" this" 的值对于Bound函数是固定的,不能通过调用和 apply 方法来覆盖功能。
已绑定和已绑定的函数不会更改" this"的值。它仍然设置为第一个绑定函数设置的值。
构造函数中" this" 的值是正在创建和初始化的对象
内联DOM事件处理程序中" this" 的值引用为其提供事件处理程序的元素。
关于this
的最详细,最全面的文章可能如下:
在JavaScript中对" this"关键字的温和解释 < / p>
此this
背后的想法是要理解函数调用类型对于设置this
值具有重要意义。
遇到无法识别this
的问题时,不要问自己:
此
来自的哪里?
但要做问自己:
如何调用函数 ?
对于箭头功能(上下文透明的特殊情况),请问自己:
this
的箭头赋值是什么值?
这种心态在处理this
时是正确的,可以使您免于头痛。
这是我所见过的最好的解释:清楚地了解JavaScript this
此 this 引用始终引用(并保留其值)对象(单个对象),并且通常在函数或方法内部使用,尽管可以在函数外部使用在全球范围内。请注意,当我们使用严格模式时,它在全局函数和未绑定到任何对象的匿名函数中都具有undefined的值。
在以下四种情况下,此可能会令人困惑:
他提供了代码示例,解释和解决方案,我认为这非常有帮助。
如果您不完全了解JS,那么很难掌握或编写比其中任何琐碎的东西都多的东西。您不能只是快速浏览一下:)我认为入门JS的最佳方法是先观看道格拉斯·克罗克福德(Douglas Crockford)的这些视频讲座- http://yuiblog.com/crockford/ ,其中介绍了有关JS的内容。
用伪古典术语来说,许多讲座讲授" this"关键字的方式是作为由类或对象构造函数实例化的对象。每次从类构造一个新对象时,请想象在幕后创建并返回" this"对象的本地实例。我记得它是这样教的:
function Car(make, model, year) {
var this = {}; // under the hood, so to speak
this.make = make;
this.model = model;
this.year = year;
return this; // under the hood
}
var mycar = new Car('Eagle', 'Talon TSi', 1993);
// ========= under the hood
var this = {};
this.make = 'Eagle';
this.model = 'Talon TSi';
this.year = 1993;
return this;
this
是JavaScript中一个被误解的概念,因为它的行为因地而异。简而言之,this
指的是我们当前正在执行的功能的"所有者" 。
此
有助于获取我们正在使用的当前对象(也称为执行上下文)。如果您了解当前函数要在哪个对象中执行,则可以轻松了解当前this
是什么
var val = "window.val"
var obj = {
val: "obj.val",
innerMethod: function () {
var val = "obj.val.inner",
func = function () {
var self = this;
return self.val;
};
return func;
},
outerMethod: function(){
return this.val;
}
};
//This actually gets executed inside window object
console.log(obj.innerMethod()()); //returns window.val
//Breakdown in to 2 lines explains this in detail
var _inn = obj.innerMethod();
console.log(_inn()); //returns window.val
console.log(obj.outerMethod()); //returns obj.val
以上,我们创建了3个具有相同名称" val"的变量。一个在全局上下文中,一个在obj内部,另一个在obj的innerMethod内部。 JavaScript通过将范围链从本地扩展到全局来解析特定上下文中的标识符。
几个可以区分this
var status = 1;
var helper = {
status : 2,
getStatus: function () {
return this.status;
}
};
var theStatus1 = helper.getStatus(); //line1
console.log(theStatus1); //2
var theStatus2 = helper.getStatus;
console.log(theStatus2()); //1
当执行第1行时,JavaScript为函数调用建立执行上下文(EC),将this
设置为对象,该对象由最后一个"。"之前的内容引用。 。因此,在最后一行中,您可以了解到a()
是在全局环境(即window
)中执行的。
此
可用于引用正在创建的对象
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
执行新的Person()
时,将创建一个全新的对象。调用Person
,并将其this
设置为引用该新对象。
function testFunc() {
this.name = "Name";
this.myCustomAttribute = "Custom Attribute";
return this;
}
var whatIsThis = testFunc();
console.log(whatIsThis); //window
var whatIsThis2 = new testFunc();
console.log(whatIsThis2); //testFunc() / object
console.log(window.myCustomAttribute); //Custom Attribute
如果我们错过了new
关键字,则whatIsThis
指的是它可以找到的最全局的上下文(window
)
如果事件处理程序是内联的,则this
引用全局对象
<script type="application/javascript">
function click_handler() {
alert(this); // alerts the window object
}
</script>
<button id='thebutton' onclick='click_handler()'>Click me!</button>
通过JavaScript添加事件处理程序时,此
是指生成事件的DOM元素。
.apply()
.call()
和.bind()
varthat=this
在JavaScript中的含义 " this"的值取决于在其中执行功能的"上下文"。上下文可以是任何对象或全局对象,即window。
因此," this"的语义不同于传统的OOP语言。这会导致问题:1.当一个函数被传递给另一个变量(很可能是回调)时;和2.从类的成员方法调用闭包时。
在两种情况下,都将其设置为窗口。
这有什么帮助? (JavaScript中的" this"最令人困惑的原因是,它通常不链接到您的对象,而是链接到当前的执行范围-可能不完全是它的工作方式,但对我来说始终像是这样-请参阅文章以获取完整说明)
有关此关键字
的一些信息让this
关键字在全局范围内登录到控制台,但没有其他任何代码
console.log(this)
在客户端/浏览器中,此
关键字是一个全局对象,它是window
console.log(this === window) // true
和
在服务器/节点/ JavaScript运行时中此
关键字也是一个全局对象,它是module.exports
console.log(this === module.exports) // true
console.log(this === exports) // true
请紧记exports
只是对module.exports
像这样用在Scope上
<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>
上面示例$(this)= $('#tbleName tbody tr')的
txt1和txt的值相同
我对this
的看法与我希望有帮助的其他答案不同。
一种查看JavaScript的方法是,只有一种方法可以调用函数 1 。是
functionObject.call(objectForThis, arg0, arg1, arg2, ...);
始终为objectForThis
提供一些值。
其他所有内容都是functionObject.call
因此,其他所有内容都可以通过将其转换为functionObject.call
来描述。
如果您只是调用一个函数,则此
是"全局对象",在浏览器中是窗口
function foo() {
console.log(this);
}
foo(); // this is the window object
换句话说
foo();
被有效地翻译为
foo.call(window);
请注意,如果您使用严格模式,则this
将是undefined
'use strict';
function foo() {
console.log(this);
}
foo(); // this is the window object
这意味着
换句话说
foo();
被有效地翻译为
foo.call(undefined);
在JavaScript中,有+
和-
和*
之类的运算符。还有一个点运算符是.
.
运算符与右侧的函数和左侧的对象一起使用时,实际上意味着"将对象作为this
传递给函数。
示例
const bar = {
name: 'bar',
foo() {
console.log(this);
},
};
bar.foo(); // this is bar
换句话说,bar.foo()
转换为consttemp=bar.foo;temp.call(bar);
请注意,函数的创建方式无关紧要(主要是...)。所有这些都会产生相同的结果
const bar = {
name: 'bar',
fn1() { console.log(this); },
fn2: function() { console.log(this); },
fn3: otherFunction,
};
function otherFunction() { console.log(this) };
bar.fn1(); // this is bar
bar.fn2(); // this is bar
bar.fn3(); // this is bar
这些都是语法糖
{ const temp = bar.fn1; temp.call(bar); }
{ const temp = bar.fn2; temp.call(bar); }
{ const temp = bar.fn3; temp.call(bar); }
原型皱纹是另一个皱纹。当您使用a.b
时,JavaScript首先会查看a
直接引用的对象中的属性b
。如果在对象上未找到b
,则JavaScript将在对象的原型中查找以找到b
。
有多种定义对象原型的方法,2019年最常见的是class
关键字。就this
而言,这无关紧要。重要的是,如果它在对象的对象a
中查找属性b
,或者在对象的原型链中找到了属性b
,则查找b
> b 最终成为一个函数,然后应用与上述相同的规则。函数b
引用将使用call
方法调用,并将a
作为objectForThis传递,如答案顶部所示。
现在。假设我们创建了一个函数,该函数在调用另一个函数之前显式设置this
,然后使用.
(点)运算符
function foo() {
console.log(this);
}
function bar() {
const objectForThis = {name: 'moo'}
foo.call(objectForThis); // explicitly passing objectForThis
}
const obj = {
bar,
};
obj.bar();
翻译后使用call
,obj.bar()
变为consttemp=obj.bar;temp.call(obj);
。当我们输入bar
函数时,我们调用foo
,但我们显式地为objectForThis传递了另一个对象,因此当我们到达foo this
时,它就是内部对象
这是bind
和=>
函数的有效作用。它们是语法更多的糖。他们有效地构建了一个新的不可见函数,就像上面的bar
一样,该函数在调用指定的任何函数之前显式设置了this
。对于绑定,此
设置为您传递给bind
的任何值。
function foo() {
console.log(this);
}
const bar = foo.bind({name: 'moo'});
// bind created a new invisible function that calls foo with the bound object.
bar();
// the objectForThis we are passing to bar here is ignored because
// the invisible function that bind created will call foo with with
// the object we bound above
bar.call({name: 'other'});
请注意,如果functionObject.bind
不存在,我们可以像这样制作自己的
function bind(fn, objectForThis) {
return function(...args) {
return fn.call(objectForthis, ...args);
};
}
然后我们可以这样称呼
function foo() {
console.log(this);
}
const bar = bind(foo, {name:'abc'});
箭头函数,=>
运算符是绑定的语法糖
const a = () => {console.log(this)};
与
相同const tempFn = function() {console.log(this)};
const a = tempFn.bind(this);
就像bind
一样,创建了一个新的不可见函数,该函数以给定的objectForThis
绑定值调用给定函数,但与bind
的对象不同要绑定是隐式的。不管使用=>
运算符时this
是什么。
所以,就像上面的规则
const a = () => { console.log(this); } // this is the global object
'use strict';
const a = () => { console.log(this); } // this is undefined
function foo() {
return () => { console.log(this); }
}
const obj = {
foo,
};
const b = obj.foo();
b();
obj.foo()
转换为consttemp=obj.foo;temp.call(obj);
意味着foo
中的箭头运算符会将obj
绑定到新的不可见函数,并返回分配给该新不可见函数的b
。 b()
将像以前一样一直工作,如b.call(window)
或b.call(undefined)
调用新的不可见函数, foo
已创建。这个不可见的函数会忽略传递给它的this
并将obj
作为objectForThis`传递给箭头函数。
上面的代码翻译为
function foo() {
function tempFn() {
console.log(this);
}
return tempFn.bind(this);
}
const obj = {
foo,
};
const b = obj.foo();
b.call(window or undefined if strict mode);
1 apply
是另一个类似于call
functionName.apply(objectForThis, arrayOfArgs);
但是从ES6的概念上讲,您甚至可以将其翻译成
functionName.call(objectForThis, ...arrayOfArgs);
this
Javascript:this
的值由如何不调用函数,在何处创建函数来确定! this
的值由点左侧的对象确定。 (全局空间中的window
)this
的值引用在其上调用事件的DOM元素。new
关键字调用in函数时,this
的值引用新创建的对象this
的值:call
,apply
,bind
let object = {
prop1: function () {console.log(this);}
}
object.prop1(); // object is left of the dot, thus this is object
const myFunction = object.prop1 // We store the function in the variable myFunction
myFunction(); // Here we are in the global space
// myFunction is a property on the global object
// Therefore it logs the window object
document.querySelector('.foo').addEventListener('click', function () {
console.log(this); // This refers to the DOM element the eventListener was invoked from
})
document.querySelector('.foo').addEventListener('click', () => {
console.log(this); // Tip, es6 arrow function don't have their own binding to the this v
}) // Therefore this will log the global object
.foo:hover {
color: red;
cursor: pointer;
}
简单答案:
"此"关键字始终取决于调用的上下文。它们在下面提到。
使用新关键字调用功能
如果使用NEW关键字调用该函数,则此函数将绑定到新创建的对象。
< pre>在上面,这将绑定到" myCar"对象
使用调用和应用方法来明确调用功能。
在这种情况下,它将绑定到明确传递给函数的对象。 / p>
function Car(){
this.name="BMW";
}
const myCar=new Car();
myCar.name; // output "BMW"
如果隐式调用了功能,则将绑定到该对象
var obj1={"name":"bond"};
function printMessage(msg){
return msg+" "+this.name;
}
const message=printMessage.call(obj1,"my name is ");
console.log(message); //HERE THIS WILL BE BOUND TO obj1 WHICH WE PASSED EXPLICITLY. SAME FOR APPLY METHOD ALSO.
在没有任何上下文的情况下调用功能,则它将被绑定到全局对象
var obj1={
"name":"bond",
getName: function () {
return this.name;
}
};
const newname=obj1.getName();
console.log(newname); //HERE THIS WILL BE BOUND TO obj1(WHITCHEVER OBJECT IS MENTIONED BEFORE THE DOT THIS WILL BE BOUND TO THAT)
在严格模式下将无法定义
const util = {
name: 'Utility',
getName: function () {
return this.name;
};
const getName=util.getName;
const newName=getName();
console.log(newName); // IF THIS EXECUTED IN BROWSER THIS WILL BE BOUND TO WINDOW OBJECT. IF THIS EXECUTED IN SERVER THIS WILL BE BOUND TO GLOBAL OBJECT