我希望找到一个“this”关键字的明确解释,以及如何正确使用它。

它的行为似乎很奇怪,我不完全明白为什么。

这是如何工作的,何时使用?


当前回答

JavaScript中的“this”这是执行上下文的财产之一。

每次执行函数时都会创建此属性,而不是在此之前。它的价值不是静态的,而是取决于它的使用方式。获取一个指向其所在函数所有者的值习惯于

“this”关键字有不同的使用方式,下面是它的示例(方法、正则函数、箭头函数、事件监听器、显式函数绑定)。

1.方法内部。

this==(对调用方法的对象)。

在上面的示例中,方法“fullName()”由对象“person”调用,因此方法“fullName()”中的值将等于对象“person”。

2.函数内部。

i) 函数声明/表达式

在松散模式下,此==窗口(对象)

在严格模式下,this==未定义

注意:使用函数声明或函数表达式方法定义函数时,此属性的工作原理相同。

ii)箭头功能:

箭头函数没有自己的此属性,它们将此属性的值作为其周围的函数。如果周围函数不存在,即如果它们是在全局级别定义的,则此==窗口(对象)

3.事件侦听器this==附加处理程序的对象。单击事件绑定到Document对象

在上面的示例中,由于单击处理程序附加到“document”对象,因此它将等于“document“对象

4.显式函数绑定(调用、应用、绑定)

call()和apply()方法是预定义的JavaScript方法。

它们都可以用来调用另一个对象作为参数的对象方法。

在上面的示例中,“printFullDetails()”中的这一点通过传递作为调用方法的第一个参数显式设置为personObj1和personObj2。

您可以在这里探索有关调用、应用和绑定方法的更多信息。

其他回答

在伪经典术语中,许多讲座教授“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;

作用域的用法如下

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

txt1和txt的值相同在上面的示例中$(this)=$('#tbleName tbody-tr')相同

JavaScript中的“this”这是执行上下文的财产之一。

每次执行函数时都会创建此属性,而不是在此之前。它的价值不是静态的,而是取决于它的使用方式。获取一个指向其所在函数所有者的值习惯于

“this”关键字有不同的使用方式,下面是它的示例(方法、正则函数、箭头函数、事件监听器、显式函数绑定)。

1.方法内部。

this==(对调用方法的对象)。

在上面的示例中,方法“fullName()”由对象“person”调用,因此方法“fullName()”中的值将等于对象“person”。

2.函数内部。

i) 函数声明/表达式

在松散模式下,此==窗口(对象)

在严格模式下,this==未定义

注意:使用函数声明或函数表达式方法定义函数时,此属性的工作原理相同。

ii)箭头功能:

箭头函数没有自己的此属性,它们将此属性的值作为其周围的函数。如果周围函数不存在,即如果它们是在全局级别定义的,则此==窗口(对象)

3.事件侦听器this==附加处理程序的对象。单击事件绑定到Document对象

在上面的示例中,由于单击处理程序附加到“document”对象,因此它将等于“document“对象

4.显式函数绑定(调用、应用、绑定)

call()和apply()方法是预定义的JavaScript方法。

它们都可以用来调用另一个对象作为参数的对象方法。

在上面的示例中,“printFullDetails()”中的这一点通过传递作为调用方法的第一个参数显式设置为personObj1和personObj2。

您可以在这里探索有关调用、应用和绑定方法的更多信息。

我对这个问题的看法与我希望有帮助的其他答案不同。

查看JavaScript的一种方法是看到只有一种方法可以调用函数1。它是

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

始终为objectForThis提供一些值。

其他一切都是functionObject.call的语法糖

因此,其他一切都可以通过它如何转换为functionObject.call来描述。

如果你只是调用一个函数,那么这就是“全局对象”,在浏览器中就是窗口

函数foo(){console.log(此);}foo();//这是窗口对象

换句话说,

foo();

被有效地转化为

foo.call(window);

请注意,如果使用严格模式,则这将是未定义的

“使用严格”;函数foo(){console.log(此);}foo();//这是窗口对象

这意味着

换句话说,

foo();

被有效地转化为

foo.call(undefined);

在JavaScript中有+、-和*等运算符。还有点运算符。

这个运算符与右侧的函数和左侧的对象一起使用时,实际上意味着“将对象作为this传递给函数”。

实例

常量bar={name:'bar',foo(){console.log(此);},};bar.foo();//这是酒吧

换句话说,bar.foo()转换为consttemp=bar.foo;临时呼叫(bar);

注意,函数的创建方式并不重要(主要是…)。所有这些都会产生相同的结果

常量bar={name:'bar',fn1(){console.log(this);},fn2:function(){console.log(this);},fn3:其他函数,};函数otherFunction(){console.log(this)};bar.fn1();//这是酒吧bar.fn2();//这是酒吧bar.fn3();//这是酒吧

同样,这些都只是语法糖

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

另一个褶皱是原型链。当您使用.b时,JavaScript首先查找属性b的a直接引用的对象。如果在对象上找不到b,则JavaScript将在对象的原型中查找b。

定义对象原型的方法多种多样,2019年最常见的是class关键字。出于这个目的,尽管这并不重要。重要的是,当它在对象a中查找属性b时,如果它在对象上找到属性b,或者在它的原型链中找到属性b(如果b最终是一个函数),那么上述规则同样适用。函数b引用将使用call方法调用,并将a作为objectForThis传递,如该答案顶部所示。

现在让我们想象一下,在调用另一个函数之前,我们创建了一个显式设置此值的函数,然后使用调用它。(点)运算符

函数foo(){console.log(此);}函数栏(){const objectForThis={name:“moo”}foo.call(objectForThis);//显式传递objectForThis}常量对象={酒吧};obj.bar();

在转换为使用调用之后,obj.bar()变为consttemp=obj.bar;临时调用(obj);。当我们进入bar函数时,我们调用foo,但我们显式地为objectForThis传递了另一个对象,所以当我们到达foo时,这是内部对象。

这是bind和=>函数有效的作用。它们是语法糖。他们有效地构建了一个新的不可见函数,就像上面的bar一样,它在调用指定的函数之前显式地设置了这个函数。在绑定的情况下,这将设置为传递给绑定的任何值。

函数foo(){console.log(此);}const bar=foo.bind({name:“moo”});//bind创建了一个新的不可见函数,该函数使用绑定对象调用foo。bar();//我们在这里传递给bar的objectForThis被忽略,因为//绑定创建的不可见函数将使用//我们在上面绑定的对象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不同的是,要绑定的对象是隐式的。当使用=>运算符时,这就是发生的情况。

所以,就像上面的规则一样

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;临时调用(obj);这意味着foo中的箭头运算符将obj绑定到一个新的不可见函数,并返回分配给b.b()的新的不可视函数。该不可见函数忽略传递给它的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);

1apply是另一个类似于调用的函数

functionName.apply(objectForThis, arrayOfArgs);

但从概念上讲,ES6甚至可以将其转换为

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

关于如何在JavaScript中解释“this”关键字,存在很多困惑。希望这篇文章能让所有这些人一劳永逸。还有更多。请仔细阅读整篇文章。预先警告,这篇文章很长。

无论使用的上下文如何,“this”总是引用Javascript中的“当前对象”。然而,“当前对象”是什么根据上下文而不同。上下文可能正好是以下6项中的1项:

全局(即在所有功能之外)内部直接“非绑定函数”调用(即尚未通过调用functionName.bind绑定的函数)内部间接“非绑定函数”通过functionName.Call和functionName.apply调用在“绑定函数”内部调用(即通过调用functionName.bind绑定的函数)通过“新建”创建对象内联DOM事件处理程序内部

以下逐一介绍了每种情况:

全局上下文(即所有功能外部):在所有功能之外(即在全局上下文中)对象”(因此“this”的值)始终是浏览器的“窗口”对象。内部直接“非绑定函数”调用:在直接“非绑定函数”调用中调用的函数调用变为“当前对象”(因此“this”的值)。如果在没有显式当前对象的情况下调用函数,则当前对象要么是“窗口”对象(对于非严格模式),要么是未定义的(对于严格模式)。中定义的任何函数(或变量)全局上下文自动成为“窗口”对象的属性。例如,假设函数在全局上下文中定义为函数UserDefinedFunction(){警报(this)}它成为窗口对象的属性,就像您定义了它作为window.UserDefinedFunction=函数(){警报(this)} 在“非严格模式”下,直接通过“UserDefinedFunction()”调用/调用此函数将自动调用/调用它作为“window.UserDefinedFunction()”,将“window”作为“UserDefinedFunction”中的“当前对象”(以及“this”的值)。在“非严格模式”中调用此函数将导致以下结果UserDefinedFunction()//显示[object Window],因为它自动被调用为窗口。UserDefined Function()在“严格模式”下,通过“UserDefinedFunction()”将“NOT”自动将其调用为“window.UserDefinedFunctions()”。因此,“当前对象”(以及“this”的值)“UserDefinedFunction”应未定义。在“严格模式”下调用此函数将导致以下结果UserDefinedFunction()//显示未定义然而,使用窗口对象显式调用它将导致以下内容window.UserDefinedFunction()//“无论模式如何,始终显示[object window]。”让我们看看另一个例子。请查看以下代码函数UserDefinedFunction(){警报(this.a+“,”+this.b+“,“+this.c+”,“+this.d”)}变量o1={a: 1中,b: 2,f: 用户定义函数}无功氧气={c: 3中,d: 4中,f: 用户定义函数}o1.f()//应显示1,2,未定义,未定义o2.f()//应显示未定义、未定义、3,4在上面的示例中,我们看到当“UserDefinedFunction”通过o1调用,“this”取值为o1显示其财产“a”和“b”的值。价值“c”和“d”的定义与o1相同没有定义这些财产类似地,当通过o2调用“UserDefinedFunction”时,“this”取o2的值,并显示其财产“c”和“d”的值。“a”和“b”的值显示为未定义,因为o2未定义这些财产。间接“非绑定函数”内部通过functionName.Call和functionName.apply调用:当通过调用“非绑定函数”时functionName.call或functionName.apply,“当前对象”(因此“this”的值)设置为传递给调用/应用的“this”参数(第一个参数)。下面的代码也演示了这一点。函数UserDefinedFunction(){警报(this.a+“,”+this.b+“,“+this.c+”,“+this.d”)}变量o1={a: 1中,b: 2,f: 用户定义函数}无功氧气={c: 3中,d: 4中,f: 用户定义函数}UserDefinedFunction.call(o1)//应显示1,2,未定义,未定义UserDefinedFunction.apply(o1)//应显示1,2,未定义,未定义UserDefinedFunction.call(o2)//应显示未定义、未定义、3、4UserDefinedFunction.apply(o2)//应显示未定义、未定义、3、4o1.f.call(o2)//应显示未定义、未定义、3、4o1.f.apply(o2)//应显示未定义、未定义、3、4o2.f.call(o1)//应显示1,2,未定义,未定义o2.f.apply(o1)//应显示1,2,未定义,未定义上述代码清楚地表明,任何“NON”的“this”值绑定函数”可以通过调用/应用来更改。此外,如果“this”参数未显式传递给调用/应用,“current object”(因此“this”的值)在非严格模式下设置为“window”,在严格模式下为“undefined”。在“绑定函数”调用(即通过调用functionName.bind绑定的函数)内部:绑定函数是其“this”值为固定的下面的代码演示了“this”在有界函数的函数UserDefinedFunction(){警报(this.a+“,”+this.b+“,“+this.c+”,“+this.d”)}变量o1={a: 1中,b: 2,f: 用户定义函数,bf:空}无功氧气={c: 3中,d: 4中,f: 用户定义函数,bf:空}var bound1=用户定义函数.bind(o1);//将函数“bound1”的“this”值永久固定到对象o1bound1()//应显示1,2,未定义,未定义var bound2=UserDefinedFunction.bind(o2);//将函数“bound2”的“this”值永久固定到对象o2bound2()//应显示undefined,undefineed,3,4var边界3=o1.f.bind(o2);//将函数“bound3”的“this”值永久固定到对象o2bound3()//应显示undefined,undefineed,3,4var绑定4=o2.f.bind(o1);//永久地将函数“bound4”的“this”值固定到对象o1bound4()//应显示1,2,undefined,undefineo1.bf=UserDefinedFunction.bind(o2)//将函数“o1.bf”的“this”值永久固定到对象o2o1.bf()//应显示未定义、未定义、3,4o2.bf=UserDefinedFunction.bind(o1)//将函数“o2.bf”的“this”值永久固定到对象o1o2.bf()//应显示1,2,未定义,未定义bound1.call(o2)//仍应显示1,2,undefined,undefine。“call”不能更改绑定函数的“this”值bound1.apply(o2)//仍应显示1,2,undefined,undefine。“apply”不能更改绑定函数的“this”值o2.bf。

以下总结了整篇文章

在全局上下文中,“this”总是指“window”对象每当调用函数时,都会在对象(“当前对象”)。如果未明确提供当前对象,当前对象是NON Strict中的“窗口对象”默认情况下,模式和严格模式中的“未定义”。非绑定函数中“this”的值是对调用该函数的上下文中的对象(“当前对象”)的引用非绑定函数中“this”的值可以由调用和应用函数的方法。“this”的值对于Bound函数是固定的,不能被函数的调用和应用方法覆盖。绑定和已绑定函数不会更改“this”的值。它保持设置为第一个绑定函数设置的值。构造函数中“this”的值是已创建并初始化内联DOM事件处理程序中“this”的值是引用指定事件处理程序的元素。