「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」
前言
💥排雷:感觉长文看起来太累,所以本文主要只说了this的四种绑定规则
💥排雷:this其他相关知识点更新中....
什么是this?
- this是JavaScript的关键字之一。它是对象自动生成的一个内部对象,只能在对象内部使用。在绝大多数情况下,函数的调用方式决定了
this
的值(运行时绑定)。this
不能在执行期间被赋值,并且在每次函数被调用时this
的值也可能会不同。
- this指向什么,完全取决于什么地方以什么方式调用,而不是创建时。
this的绑定规则
在函数的执行过程中调用位置如何决定 this 的绑定对象。 你必须找到调用位置,然后判断需要应用下面四条规则中的哪一条。
默认绑定
最常用的函数调用类型:独立函数调用。可以把这条规则看作是无法应用 其他规则时的默认规则。
🎨先看一段代码
function foo() {
console.log( this.a );
}
var a = 2;
foo(); // 2
📖可以看到当调用 foo() 时,this.a 被解析成了全局变量 a。为什么?
因为在本例中,函数调用时应用了this的默认绑定,因此 this 指向全局对象。
📖怎么知道这里应用了默认绑定?
可以通过分析调用位置来看看 foo() 是【如何调用】的。在代码中,foo() 是直接使用不带任何修饰的函数引用进行调用的,因此只能使用默认绑定,无法应用其他规则。
隐式绑定
对象方法调用,考虑调用位置是否有上下文对象,或者说是否被某个对象拥有或者包含
function foo() {
console.log( this.a );
}
var obj = { a: 2, foo: foo };
obj.foo(); // 2
声明了一个foo()方法,函数被调用时 obj 对象“拥有”或者“包含”它,调用位置会使用 obj 上下文来引用函数。
当 foo() 被调用时,它的落脚点指向 obj 对象。当函数引用有上下文对象时,隐式绑定规则会把函数调用中的 this 绑定到这个上下文对象。因为调用 foo() 时 this 被绑定到 obj,因此 this.a 和 obj.a 是一样的。
显示绑定
隐式绑定时,我们必须在一个对象内部包含一个指向函数的属性,并通过这个属性间接引用函数,从而把 this 间接(隐式)绑定到这个对象上。
📖那么如果我们不想在对象内部包含函数引用,而想在某个对象上强制调用函数,该怎么做呢?
可以使用函数的 call(..) 和 apply(..) 方法来解决这个问题。
它们的第一个参数是一个对象,它们会把这个对象绑定到 this,接着在调用函数时指定这个 this。因为你可以直接指定 this 的绑定对象,因此我们称之为显式绑定。
function foo() {
console.log( this.a );
}
var obj = { a:2 };
foo.call( obj ); // 2
通过 foo.call(..),我们可以在调用 foo 时强制把它的 this 绑定到 obj 上。
new绑定
首先要知道JavaScript 中的“构造函数”,不能说是一种特殊的函数类型,它们只是被 new 操作符调用的普通函数而已。(new是JavaScript中的一个操作符)
function foo(a) {
this.a = a;
}
var bar = new foo(2);
console.log( bar.a ); // 2
使用 new 来调用 foo(..) 时,我们会构造一个新对象并把它绑定到 foo(..) 调用中的 this 上。
new是最后一种可以影响函数调用时this绑定行为的方法,我们称之为 new 绑定。
参考资料:
🎨【点赞】【关注】不迷路,更多前端干货等你解锁
往期推荐