【一篇就够】浅析this–this绑定规则及优先级
1.什么是this?
1.1 this到底是什么?
科学的尽头是神学,this关键字是JS中最复杂的机制之一。它是一个很特别的关键字,往往被自动定义到所有函数的作用域中。使用恰当,往往会使得一段代码更加精短且强大,但往往会出现许多意外事件,使得它不稳定。实际上,this关键字并没有那么神秘,但是在缺乏清晰的认识下,this就像是一个魔法。今天,就让我们来揭开它那神秘的面纱。
现在先声明一下,this是在运行时绑定的,它绑定哪个对象,完全依赖于它在声明时候的调用!**this的绑定和声明位置并没有任何关系,只取决于它的调用位置**。
来看一个实例:
function foo(){console.log(this);
}
foo() //window
let obj ={ name:'sss', foo:foo
}
obj.foo()//{name:'sss',foo:function}
foo.call("abc")// 生成包装类型对象,String {'abc'}
<img src=“https://juejin.cn/ “点击并拖拽以移动”” style=“margin: auto” />
我们会发现,定义一个函数,用三种不同的方式调用,会产生三种不同的结果。一个函数调用方式不同this指向也不尽相同,为什么会出现这么令人费解的现象呢?是因为在JavaScript中函数的this是动态绑定的(箭头函数除外)。
1.2 为什么要用this?
this机制是如此的复杂,那么我们为什么还要使用它呢?它到底有什么用呢?它是否真的值得我们如此深入的去了解它吗?带着这一系列问题,我来为大家解释一下为什么我们还是要坚持使用如此复杂的this。
function upcase() { return this.name.toUpperCase();};
function test() { let demo = "demo:" + upcase.call(this);console.log(demo);};
let name1 = { name: "demo1"};
let name2 = { name:"demo2" };
test.call(name1); //demo:DEMO1
test.call(name2); //demo:DMEO2
<img src=“https://juejin.cn/ “点击并拖拽以移动”” style=“margin: auto” />
如果未接触this或者对JS语法了解不够深入,那么这段代码往往是比较晦涩的。在这里,我们通过使用this,发现在不需要给upcase()和test()函数传入对象就可以使用其函数的功能。在过去不提及this,这就是一个神话。如果不使用this,就需要给upcase函数和test函数显式传入一个上下文对象,才可以完成这一操作,代码如下:
function upcase(name) { return name.name.toUpperCase();};
function test(name) { let demo = "demo:" + upcase(name);console.log(demo);};
let name1 = {name: "demo1"};
let name2 = {name:"dmeo2"};
test(name1); //demo:DEMO1
test(name2); //demo:DMEO2
<img src=“https://juejin.cn/ “点击并拖拽以移动”” style=“margin: auto” />
通过两段代码比较,我们可以发现,使用**this可以更加优雅的来传递一个对象的引用**,可以使得我们的代码更加简洁且易于使用。尤其是在我们使用多个函数互相调用,不断套娃时,我们显示的使用的上下文传递对象,很容易使得代码混乱,且使代码可读性降低,使用this则不会这样。所以,使用**this更有利于自己代码开发和后期代码维护。**
1.3 this的作用域?
人们常常