对this的二次认知(一)
😸😸😸最近在深入学习js
的时候,js
的复杂性在不断地刷新本人的认知,幸运的是之前对js
还是有一点基础的,所以学起来更多的是收获惊喜,每一个小小的代码语句背后,都有非常奇妙的引擎处理过程,这也成就的js
的与众不同。
🐧🐧🐧之前已经写过一篇关于this
的文章,那已经是半年前的暑假了,现在回顾起来,当时写this
的时候还只是小白,写得并不是很全面,起码没我现在对this
的理解更清晰,更深入,所以来更新一下本人对于this
的理解。
1. 为什么会存在this呢?
🌸1. 语言角度:几乎常见的面向对象语言中都存在this
这个关键字,比如Java
、C++
,但是this
通常只会出现在类的方法中,这一点我相信接触过上述语言的都清楚,而js
中的this
更加灵活,不懂得this
的指向,就其对于js
重要性而言我觉得你有点遗憾了。
🌸2.灵活性:this
的指向并不是固定的,在任何时候,当我们清楚了this
的指向,我们书写代码的时候更加方便,灵活。
可能其中还有很多原因,但还得等本人功力加深再谈。
2. this指向什么呢?
前奏知识:
❄️1.所有的函数在被调用时,都会创建一个函数执行上下文
❄️2.这个上下文中记录着函数的调用栈、VO
对象、作用域链、执行代码等等
❄️3.this
也是一条其中的记录
❄️4.this
通常在函数中使用
❄️5.this
指向并不固定(一般情况指向一个对象),跟函数定义的位置并无瓜葛
❄️6.任何情况下,this
的值不可修改
❗️❗️❗️this
的绑定与函数的调用方式以及调用位置有关系
主要有如下四种绑定规则:
3.规则一:默认绑定
🍁什么情况下使用默认绑定呢?
独立函数调用:可以理解成函数没有被绑定到某个对象上进行调用,默认指向windwo
🍁案例一:
function foo() {
console.log(this);
}
//独立函数调用
foo() //window
🍁案例二:
var obj = {
name: "obj",
foo: function () {
console.log(this);
}
}
//obj.foo是函数的地址
var fn = obj.foo
//独立函数调用
fn()//window
🍁案例三:
//这里参数是函数
function fn(foo) {
foo()
}
var obj = {
name: "obj",
foo: function () {
console.log(this);
}
}
//独立函数调用 obj.foo代表函数地址 但函数是自己执行
fn(obj.foo) //window
🍁案例四:
function test1() {
console.log(this); //window
test2()
}
function test2() {
console.log(this); //window
test3()
}
function test3() {
console.log(this); //window
}
//独立函数调用
test1()
4.规则二:隐式绑定
🌿函数调用方式是通过某个对象调用的(函数作为对象的属性,俗称:对象的方法)
🌿案例一:
var obj = {
name: "obj",
foo: function () {
console.log(this);
}
}
obj.foo() //obj对象
🌿案例二:
function foo() {
console.log(this);
}
var obj1 = {
name: "obj1",
foo: foo
}
var obj2 = {
name: "obj2",
obj1: obj1
}
//这里的调用对象不是obj2,obj2只是找到obj1的媒介,foo属性仍然挂在obj1对象上
obj2.obj1.foo() //obj1对象
🌿案例三:
var obj1 = {
name: "obj1",
foo: function () {
console.log(this);
}
}
var obj2 = {
name: "obj2"
}
obj2.bar = obj1.foo
//bar作为obj2的属性被调用
obj2.bar() //obj2对象
5.规则三:显示绑定
🌵通过js
提过内置函数修改this指向
🌵call
、apply
、bind
这里不谈这三种函数的使用方法和区别
🌵案例一:
function foo() {
console.log(this);
}
foo.call(window) //window
foo.call("sss") //String {'sss'}
foo.call(156) //Number {156}
🌵案例二:固定函数的this绑定
function foo() {
console.log(this);
}
var bar = foo.bind("me")
bar() //bar永远指向 String {'me'}
6.规则四:new绑定
🌏js
中的函数可以当作一个类的构造器来使用,调用时使用new
关键字
🌏使用new
关键字来调用函数,会执行如下的操作:
- 创建一个全新的空的对象
- 这个新对象会和
prototype
连接 - 空的对象被分配给
this
(this
指向这个对象) - 函数体执行,通常会通过
this
为这个对象添加新的属性 - 函数默认返回
this
,也就是这个对象
🌏案例一:
function Person(name) {
this.name = name
console.log(this); //Person {name:'jack'}
//默认返回this
}
var p = new Person('jack')
console.log(p);//Person {name:'jack'}
7.总结
💖1.我觉得上述四个绑定规则如果能够掌握,起码this
在你平常写代码的时候能够拿捏自如,相比我的上一篇关于this
指向来说,这次写得就很系统化,基本涵盖了this的所有使用情况,理解才是王道
💖2.我万万没有想到我写到这里的时候已经花了两个小时了,但关于this
的认知并没有写完,下一篇博客将完结我对this
的理解
💖3.虽然花费了两个小时,但是很有价值,我觉得我真正在这个过程中掌握这些知识的,前几天看了一篇优秀学习方法:费曼学习法的博客,学习过程中,我们更需要主动学习,而不是被动学习,博客地址我分享在这里:
优秀的学习方法 - 费曼学习法 - 掘金 (juejin.cn)
借用一句电影台词作为结束语吧:
成年人的生活里,没有容易二字。
——《天气预报员》
哈哈,我还不想把自己当作成年人看待,但悄然发现自己的思想已不再稚嫩。