解密JavaScript中的this关键字(法外篇)
"在JavaScript中,this关键字的行为由一系列规则确定。然而,除了这些规则之外,还存在一些特殊情况需要额外注意。本文将探讨JavaScript中this规则之外的一些情况。"
引言
JavaScript中的this关键字在函数执行过程中扮演着重要的角色,它决定了函数在运行时的上下文环境。在之前的文章中,我们讨论了this的四种标准规则:默认绑定、隐式绑定、显式绑定和new绑定。然而,除了这些规则之外,JavaScript还存在一些特殊情况需要特别留意。本文将探索这些规则之外的情况,帮助您更好地理解和应用this关键字。
正文
忽略显示绑定
在显示绑定中,如果传入null或undefined作为参数,this的绑定会被忽略,使用默认规则。考虑以下示例:
javascriptCopy code
function foo() {
console.log(this);
}
var obj = {
name: "why"
}
foo.call(obj); // 输出:obj对象
foo.call(null); // 输出:window
foo.call(undefined); // 输出:window
var bar = foo.bind(null);
bar(); // 输出:window
在上述示例中,通过call
方法将函数foo
与对象obj
绑定,此时this
指向obj
对象。然而,当传入null
或undefined
时,显示绑定被忽略,this使用默认规则,指向全局对象window
。
间接函数引用
另一个情况是通过间接引用来创建函数的引用,此时使用默认绑定规则。考虑以下示例:
javascriptCopy code
var num1 = 100;
var num2 = 0;
var result = (num2 = num1);
console.log(result); // 输出:100
function foo() {
console.log(this);
}
var obj1 = {
name: "obj1",
foo: foo
};
var obj2 = {
name: "obj2"
}
obj1.foo(); // 输出:obj1对象
(obj2.foo = obj1.foo)(); // 输出:window
在上述示例中,(num2 = num1)
的结果是num1
的值,即100
。对于函数赋值 (obj2.foo = obj1.foo)
,由于立即调用了函数,因此遵循默认绑定规则。在函数foo
中,this
会绑定到全局对象window
。
ES6箭头函数
在ES6中引入了箭头函数,它们是一种非常实用的函数类型。箭头函数不使用四种标准规则来确定this的值,而是根据外层作用域来决定this的值。
考虑以下模拟网络请求的示例:
javascriptCopy code
var obj = {
data: [],
getData: function() {
var _this = this;
setTimeout(function() {
// 模拟获取到的数据
var res = ["abc", "cba", "nba"];
_this.data.push(...res);
}, 1000);
}
}
obj.getData();
在上述示例中,我们使用setTimeout
来模拟网络请求。为了能够在回调函数中访问到obj
对象,我们在外部定义了变量_this
来保存obj
对象的引用,然后在setTimeout
的回调函数中使用_this
来操作data
数组。
从ES6开始,我们可以使用箭头函数来简化代码:
javascriptCopy code
var obj = {
data: [],
getData: function() {
setTimeout(() => {
// 模拟获取到的数据
var res = ["abc", "cba", "nba"];
this.data.push(...res);
}, 1000);
}
}
obj.getData();
由于箭头函数不绑定this对象,它会从上层作用域中找到对应的this值。因此,箭头函数中的this会指向外层作用域中的this,即obj
对象。
思考一下,如果将getData
也改为箭头函数,那么setTimeout
的回调函数中的this将指向谁呢?答案是window
,因为箭头函数会继续向上层作用域查找,最终找到全局作用域,而在全局作用域中,this代表的就是window
对象。
javascriptCopy code
var obj = {
data: [],
getData: () => {
setTimeout(() => {
console.log(this); // 输出:window
}, 1000);
}
}
obj.getData();
总结
本文介绍了JavaScript中this规则之外的一些情况。了解这些特殊情况可以帮助我们更好地理解和应用this关键字。通过忽略显示绑定中的null和undefined参数,我们可以使用默认规则确定this的值。在间接函数引用中,函数被直接调用时会遵循默认绑定规则。此外,ES6的箭头函数不会绑定this对象,而是根据外层作用域来决定this的值。我们希望本文能够帮助您更好地理解和应用JavaScript中this规则之外的情况。
转载自:https://juejin.cn/post/7245753944180572219