从this的5种绑定开始

:star: js中共有5中this的绑定,关于this的指向之前有点晕,现在好好梳理一下

其中优先级从高到低分别是:new绑定、显式绑定、隐式绑定、默认绑定。注意默认绑定通常指向全局对象,严格模式下指向undefined。

默认绑定

即没有调用前缀的情况下,即函数调用,在浏览器中this指向全局对象window(非严格模式),严格模式指向undefined。

隐式绑定

函数调用的前面有一个对象,即方法调用,函数的this指向对象。

当函数调用有多个对象时,this指向最近的对象。

1
2
3
4
5
6
7
8
9
10
11
12
function fn() {
console.log(this.name);
};
let obj = {
name: '时间飞行',
func: fn,
};
let obj1 = {
name: '听风是风',
o: obj
};
obj1.o.func() //时间飞行

当去掉obj中的name: '时间飞行'时,输出的是undefined,属于原型链查找,obj和obj1的原型并不相同

作用域链与原型链的区别:

作用域链查找是指,当访问一个变量时,当前作用域没有找到,便向父级作用域寻找,一直向上,顶端是全局对象window,如果window都没有这个变量就报错。

原型链查找是指,访问一个对象的属性,当前对象没有找到,便向原型的属性查找,一直向上,顶端是null,如果没找到返回undefined。

隐式丢失:

1
2
3
4
5
6
7
8
9
10
11
12
13
var name = '时间飞行';
let obj = {
name: '听风是风',
fn: function () {
console.log(this.name);
}
};

function fn1(param) {
param();
};
fn1(obj.fn);//时间飞行 因为是单纯传入函数
fn1(obj.fn());//听风是风 传入的是函数的调用

显式绑定

通过apply、call、bind改变this的指向

三者的区别在于:

  • call、apply在改变this的同时会执行函数,bind改变this后返回函数,需要手动执行函数。
  • bind属于硬绑定,返回的函数的this不能通过call,apply,bind改变,call和apply只适用当前绑定。
  • call传入的参数是散列,apply传入的是数组。

new绑定

this指向新对象

this绑定优先级:

  • 显示绑定>隐式绑定>默认绑定
  • new绑定>隐式绑定>默认绑定

需要注意的是,不存在同时的显示绑定和new绑定

箭头函数

箭头函数没有自己的this,将当前执行上下文的上文作为this。

👇关于this指向的题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*非严格模式*/

var name = 'window'

var obj1 = {
name: '听风是风',
fn1: function () {
console.log(this.name)
},
fn2: () => console.log(this.name),
fn3: function () {
return function () {
console.log(this.name)
}
},
fn4: function () {
return () => console.log(this.name)
}
}
var obj2 = {
name: '时间飞行'
};

obj1.fn1();//?
obj1.fn1.call(obj2);//?

obj1.fn2();//?
obj1.fn2.call(obj2);//?

obj1.fn3()();//?
obj1.fn3().call(obj2);//?
obj1.fn3.call(obj2)();//?

obj1.fn4()();//?
obj1.fn4().call(obj2);//?
obj1.fn4.call(obj2)();//?

输出如下:

听风是风 this隐式调用,指向obj1对象

时间飞行 显示改变this指向obj2
window 比较特殊的是fn2是箭头函数,只与上下文有关
window 箭头函数没有this,无法显示改变指向
window 相当于let fn=obj1.fn(),window.fn(),window隐式调用了
时间飞行 显示改变了this指向
window 最后window隐式调用了
听风是风 返回的是闭包中的箭头函数,隐式调用不能改变this
听风是风 同上
时间飞行 改变fn4的this,指向obj2,箭头函数就使用上层上下文(obj2)的属性

参考文章:

带你彻底搞懂 JS 中 this 机制

查看评论