「前端」JavaScript中this绑定规则

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_26377547/article/details/101981249

近些天在阅读《你不知道的JavaScript》的过程中,解决了一个一直以来都很困惑的问题:this指向
这篇博客用来记录JavaScript中this的绑定规则备忘。

绑定规则

默认绑定

function foo() {
	console.log(this.a);
}
var a = 2;
foo();	// 2

上面这段代码中,foo()中的this指向了全局对象window),原因是什么呢?
我们看到foo()被调用的位置,很显然是在全局作用域下被调用,没有使用任何修饰,因此只能使用默认绑定规则,指向全局对象
foo()是运行在非严格模式下的,若是运行在严格模式下,则全局对象无法使用默认绑定规则,this就会被绑定到undefined

function foo() {
	"use strict";
	console.log(this.a);
}
var a = 2;
foo();	// TypeError: this is undefined

隐式绑定

function foo() {
	console.log(this.a);
}
var obj1 = {
	a:2,
	foo:foo
}
obj1.foo();	// 2 

当函数引用存在上下文对象时,隐式绑定规则会将函数调用中的this绑定到这个上下文对象。
这句话的意思是什么呢?
就是函数调用时是哪个对象的属性,那么函数中的this就指向这个对象。
假定我们还有一个obj2对象:

var obj2 = {
	a:5,
	foo:foo
}
obj2.foo();	// 5

则函数foo()输出的结果就为5
隐式绑定存在一个问题:隐式丢失

隐式丢失
function foo() {
	console.log(this.a);
}
var obj = {
	a:2,
	foo:foo
}
var a = 'global';
var bar = obj.foo;
bar();	// global

为什么这里输出的是globalbar不是obj.foo的引用吗?
原因是bar只引用了函数foo()本身,仅此而已,并没有将上下文对象也包括在内。
类似的情况也经常发生在回调函数中,例如:

setTimeout(obj.foo, 100);	// global

如何解决隐式丢失问题呢?接下来介绍到的显式绑定就能比较方便地解决这个问题。

显式绑定

JavaScript中提供了三个可以实现this绑定的方法,分别是call()apply()bind()

function foo() {
	console.log(this.a);
}
var obj = {
	a:2,
	foo:foo
}
var a = 'global';
var bar = foo.bind(obj);
bar();	// 2
function foo() {
	console.log(this.a);
}
var obj = {
	a:2,
	foo:foo
}
var a = 'global';
foo.call(obj);	// 2

apply()方法的使用方式与call()方法类似,两者的区别就在于接收参数的方式不同,前者是以数组的形式接收,而后者是按顺序逐个接收。
至于三个方法的详细区别及用法,可以移步这里:https://juejin.im/post/582bcd36d203090067edb8a0
三个方法都能手动改变this的指向。

new绑定

使用new来调用函数,或者说发生构造函数调用时,会自动执行下面的操作:

  1. 创建一个全新的对象。
  2. 这个新对象会被执行原型连接。
  3. 这个新对象会被绑定到函数调用的this
  4. 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象。

上面这段描述可能看了很懵逼,我们来看个例子就明白了:

function foo(a) {
	this.a = a;
}
var bar =  new foo(2);
console.log(bar.a);	// 2

使用new来调用foo()是,会构造一个全新的对象并将其绑定到foo()调用中的this上。

以上就是所有关于JavaScript中this指向问题的绑定规则,后续关于绑定优先级的问题,将会另写一篇博客记录。

猜你喜欢

转载自blog.csdn.net/qq_26377547/article/details/101981249
今日推荐