前言
互联网上有很多有关此工作原理的信息,但一直以来,我几乎没有足够的文字来充分理解它。
不过,最近看来,在我看来,我还是愿意与您分享。
没有很多话
我们将介绍简单和复杂的示例-每个人都会感兴趣。
我们要注意两个要点:
(1)对于通过function(){}声明的函数,这是在调用时计算的。
(2)对于箭头函数,在创建函数时定义。
让我们从一些简单的例子开始。
function globalFunc() {
console.log(this);
}
const globalArrowFunc = () => {
// , this - window/undefined
// , use strict this === undefined
console.log(this);
}
globalFunc(); // undefined
globalArrowFunc(); // undefined
如果我们将这些函数添加到对象中,该怎么办:
const cat = {
name: 'Pirate',
globalFunc,
globalArrowFunc
};
cat.globalFunc(); // { name: 'Pirate', ... }
cat.globalArrowFunc(); // undefined
让我们弄清楚。
调用cat.globalFunc()返回了一个cat对象。为了便于理解,您可以这样想:“当调用通过function(){}声明的函数时,它将等于point之前的对象”。
那么为什么cat.globalArrowFunc()为我们返回未定义?事实是,箭头函数的this值是在创建时确定的,而当我们创建它时,this值是不确定的。
现在让我们用两个方法创建一个对象:
const dog = {
name: 'Viking',
//
//
localFunc: function() {
console.log(this);
},
localArrowFunc: () => {
console.log(this);
}
};
dog.localFunc(); // { name: 'Viking', ... }
dog.localArrowFunc(); // undefind
这是为什么?
dog.localFunc()-因为指向狗之前的对象。
dog.localArrowFunc()-因为在对象内部这也是一个全局对象,这意味着我们不确定。
让我们的例子复杂一些。
const dog = {
name: 'Viking',
localFunc: function() {
const arrowFuncInLocalFunc = () => {
console.log(this);
};
function funcInLocalFunc() {
console.log(this);
};
arrowFuncInLocalFunc(); // 1
funcInLocalFunc(); // 2
},
localArrowFunc: () => {
const arrowFuncInLocalArrowFunc = () => {
console.log(this);
};
function funcInLocalArrowFunc() {
console.log(this);
};
arrowFuncInLocalArrowFunc(); // 3
funcInLocalArrowFunc(); // 4
}
};
dog.localFunc();
// 1 - { name: 'Viking', ... }
// 2 - undefind
dog.localArrowFunc();
// 3 - undefind
// 4 - undefind
让我们弄清楚!
(1)arrowFuncInLocalFunc()// {name:'Viking',...}
为什么会这样?
因为创建对象时,我们将其编写为localFunc函数。而且,正如我们从前面的示例中所记得的那样,对于她来说,这是指向对象的对象,即{name:'Viking',...}。现在让我们来谈谈arrowFuncInLocalFunc函数本身-调用localFunc时会立即创建该函数,并记住其创建位置的this值。因此,我们得到了arrowFuncInLocalFunc返回我们{name:'Viking',…}。
(2)funcInLocalFunc()//未定义
为什么会发生这种情况?
如前所述,对于通过function(){}声明的函数,此值在调用时确定,并且等于point之前的对象。在这种情况下,我们在该点之前没有对象,这意味着这是一个全局对象,或者在我们的情况下是未定义的。
(3)arrowFuncInLocalArrowFunc()//未定义
为什么会这样?
此示例与(1)非常相似,仅在同一arrow函数内创建了arrowFuncInLocalArrowFunc函数。我们还记得箭头函数在声明时从其环境写入此值。但是,我们的函数是在localArrowFunc内部创建的,对此未定义。这意味着对于arrowFuncInLocalArrowFunc它将是未定义的。
(4)funcInLocalArrowFunc()//未定义
为什么会这样?
正是由于与funcInLocalFunc(2)中的原因相同,
让我们来看另一个示例:
const cat = {
name: 'Tom',
getFuncWithTomName: function() {
return () => {
console.log(this.name);
}
}
};
const mouse = {
name: 'Jerry',
logName: cat.getFuncWithTomName()
};
mouse.logName(); // Tom o_O !?
这是因为getFuncWithTomName创建并返回箭头函数,并且在创建箭头函数时,这与getFuncWithTomName相同。对于getFuncWithTomName,这是点(猫)之前的对象。
总
箭头函数的上下文在创建时确定。
函数(){}的上下文是在调用它们时确定的,并且它等于指向该对象之前的对象。