「这是我参与2022首次更文挑战的第29天,活动详情查看:2022首次更文挑战」。
今天我们来学习总结下this的绑定规则。
- 规则一:默认绑定
- 规则二: 隐式绑定
- 规则三: 显示绑定
- 规则四: new绑定
本篇文章中将介绍规则一默认绑定和规则二隐式绑定。
规则一:默认绑定
什么情况下使用默认绑定呢?独立函数调用。
独立函数调用我们可以理解为函数没有绑定到某个对象上进行调用,即函数没有调用主题。
接下来我们来看几个案例。
案例一
function foo() {
console.log(this);
}
foo()
我们再来看下其他方式。
案例二
我们来思考下以下代码的三个this分别指向什么呢?
function foo1() {
console.log(this);
}
function foo2() {
console.log(this);
foo1()
}
function foo3() {
console.log(this);
foo2()
}
foo3()
foo1、foo2、foo3在调用的时候是独立调用,并没有通过info.foo1()等方式进行调用。
案例三
var obj = {
name: 'haha',
foo: function() {
console.log(this);
}
}
var bar = obj.foo
bar()
当我们调用foo函数的时候,也是独立调用,所以this指向的是window。
案例四
function foo() {
console.log(this);
}
var obj = {
name: 'haha',
foo: foo
}
var bar = obj.foo
bar()
案例五
function foo() {
function bar() {
console.log(this);
}
return bar
}
var fn = foo()
fn()
接下来,我们改变一下案例五的调用方式,不直接调用fn。
var obj = {
name: 'haha',
eating: fn
}
obj.eating()
我们可以看到this指向的是obj对象,这是因为this进行了隐式绑定。我们接下来进行总结。
规则二: 隐式绑定
另外一种比较常见的调用方式是通过某个对象进行调用。也就是它的调用位置中,是通过某个对象发起的函数调用。
我们有个object对象,然后通过object.fn()进行调用。object对象会被js引擎绑定到fn函数中this里面。js引擎会自动帮助我们绑定,所以我们称之为隐式绑定。
案例一
function foo() {
console.log(this);
}
var obj = {
name: 'haha',
foo: foo
}
obj.foo()
案例二
var obj = {
name: 'haha',
eating: function() {
console.log(this.name + '在吃饭');
},
running: function() {
console.log(this.name + '在跑步');
}
}
obj.eating()
obj.running()
在这个例子中,由于obj调用了eating和running方法,所以this指向的obj对象,进行了隐式绑定。在上篇文章中,我们讲到了log中的this改成obj也是可以获取到obj对象中的name属性。
我们修改下调用方式,那么结果会是怎样呢?
var fn = obj.eating
fn()
以上是进行了独立绑定,this指向的window,而在window对象中本身是带有name属性的,但是name没有值。
打印window对象。
案例三
var obj1 = {
name: 'obj1',
foo: function() {
console.log(this);
}
}
var obj2 = {
name: 'obj2',
bar: obj1.foo
}
obj2.bar()
foo被调用的时候,它是被obj2进行调用起来的,obj2会自动绑定到foo中的this,所以foo中this指向的是obj2。