「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战」
上篇我们已经了解了函数调用中 this 绑定的四条规则,但是,如果某个调用位置可以应用多条规则该怎么办?为了 解决这个问题就必须给这些规则设定优先级,这就是我们接下来要介绍的内容。
前言
规则回顾
-
默认绑定
例:
function foo(){...} foo()
,foo 中的 this 就是 window.(严格模式下默认绑定到undefined), 这样的绑定方式叫默认绑定 .
-
隐式绑定
函数是在某个上下文对象下被调用, this绑定的是那个上下文对象。
例 :
function foo(){...}; var obj = { foo : foo }; obj.foo();
。foo 中的 this 就是 obj 。这样的绑定方式叫隐性绑定
-
显示绑定
函数是使用
call,apply,bind
来调用的,this绑定的是 call,apply,bind 的第一个参数。、例:
function foo(){...}; foo.call(obj);
。foo 中的 this 就是 obj , 这样的绑定方式叫显性绑定 .
-
new绑定
函数被
new
修饰,this绑定的是新创建的对象例:
var bar = new foo();
函数 foo 中的 this 就是一个叫foo的新创建的对象 , 然后将这个对象赋给bar , 这样的绑定方式叫 new绑定 。
优先级分析
毫无疑问,默认绑定的优先级是四条规则中最低的,所以我们可以先不考虑它。
隐式绑定和显式绑定哪个优先级更高?
function foo() { console.log( this.a ); }
var obj1 = { a: 2, foo: foo };
var obj2 = { a: 3, foo: foo };
//隐式绑定
obj1.foo(); // 2
obj2.foo();// 3
//显示绑定
obj1.foo.call( obj2 ); // 3
obj2.foo.call( obj1 ); // 2
结论:显式绑定优先级大于隐式绑定
new 绑定和隐式绑定的优先级谁更高?
结论:当同时存在于new关键字绑定和隐式绑定时,this绑定了foo构造函数,所以new关键字的优先级高于隐式绑定
new 绑定和显示绑定的优先级比较?
结论:当同时存在于new关键字绑定和显示绑定时,this绑定了bar构造函数,所以new关键字的优先级高于显示绑定。
箭头函数的this
注意,箭头函数没有自己的this,它的this来源于上级作用域。
如以上示例,同样是调用foo函数,因为箭头函数不绑定this,所以去foo函数的上级查找this,找到了全局对象window。
总结
四种绑定的优先级顺序为
new关键字 > 显式绑定 > 隐式绑定 > 默认绑定
判断this调用规则
- 函数是否存在new绑定调用:如果是的话this绑定到新创建的对象上。
var bar = new foo()
- 函数是否通过apply、call、bind显示绑定:如果是的话,this绑定到指定对象上。
var bar = foo.call(obj2)
- 函数是否在对象方法隐式调用:如果是的话,this绑定到调用对象。
var bar = obj1.foo()
- 如果上面三条都不满足的话:在严格模型下,this绑定到undefined,在非严格模式下,this绑定到全局对象上。
var bar = foo()
参考资料:
🎨【点赞】【关注】不迷路,更多前端干货等你解锁
往期推荐