前言
前几天想看看react项目,然后视频推荐先学会axios,然后axios视频推荐先学promise。在学完基操后,挑战手写promise,然后遇到了问题,总结:this真是个好东西,可惜我不懂。
一、问题
看如下代码:
问题: 1.第6行打印的是什么 2.第15行打印的结果又是什么
这里输出一下结果: 如果这里你回答对了,那请划走,毕竟,这你都会了。
二、问题分析
1.代码含义
- 构造函数
不难看出这是一个es5构造函数的使用,先是定义了一个es5构造函数,传入的参数是一个函数fun。构造函数demo内部会定义两个属性(通过this),然后又定义了一个用来改变属性的函数change(),传入的参数fun会在内部调用change函数。 - 函数调用
通过new构造函数创建一个新的对象demo1,demo中的属性就会指向demo,构造函数内部以es6箭头函数形式传入一个函数作为参数,然后函数内部传参change()。
其实这段代码,就是在伪写手敲promise内部中的一个步骤,有兴趣挑战一下手敲promise。 2.问题 看到这里,上一板块的问题你可能想错了,没错,change内部的this指向的是window而不是demo!!!!,并且,demo的属性也没有改变,change似乎失效了。 到这里,你可能有两个问题:
1.第六行为什么打印的是window 2.怎么做才能让change动起来
首先解释一下第一个问题 最主要原因:函数自运行问题, 首先demo是个es5构造函数,其this指向调用它的对象,调用!!!,对,就是调用,我们的change也是一个es5函数,所以他也是这样,但是你看调用时参数里的change(),又是谁调用了它呢?? 个人理解所谓调用,起码函数前面要有东西,就像对象内部函数的调用(es5函数调用)但再看我们的change(),孤单一个函数运行,前无古人,后无来者…所以change在这里是自运行的,没有对象在调用它(没有对象…) 自运行的es5函数内部this指向window 所以打印的结果是window
三、解决
这个时候的输出就是我们的理想输出了: 那么问题又来了
为什么这么改就能实现呢
先来观察下面代码的三处输出,猜一下结果都是什么: 公布结果:
逐个解释:
- 这里的this是demo构造函数内部的,我们使用了 new关键字进行调用,所以这个时候的demo函数被调用,this指向调用的对象,new关键字原因,最后这个this指向了函数本身demo,所以1处打印初始化的demo对象。
- 这里的问题前面说过,自运行函数,change函数没有被调用,指向window。
- 这里的this还在demo函数里面,指向demo,但前面已经调用了change,所以属性值发生改变。
到这我们就可以提出最后一个问题,属性值是怎么通过一个小小的self改变的?
原理很简单,因为调用demo构造函数,初始时demo的两个属性会指向demo1,也就是demo1此时也有两个属性了,在调用change时,change本身是不拥有self这个属性的,self是demo里的属性,它变向指向this,所以change此时会将self的两个属性改变,而self也是指向demo1的。对于一个对象中的属性,键名相同,键值不同的赋值会产生覆盖效果,最后使得demo中的两个属性值改变,得到最后效果。
|