00:01
这一节我们来学习递归侦测对象全部属性。看见这个标题呢,估计你就想到了我们之前呢一个对象OB勾。他实际上并不能,嗯,通过用递归的手段把这个OB勾这个对象身上所有的属性。对吧,哎不能,呃,所有的属性诶都不能说直接给它都变成响应式的啊,就都给他们赋予get和set啊,你比如说现在我们现在他有这个。嗯呃,比如说天生就有A属性或者B属性,那这个时候呢,你都给一呃,一上来就要去写这个A和B,然后万一这个A属性里头呢,又是一个对象,它又有M属性,M属性又是对象,对象里头又有N属性,N属性呢也是一个对象,那这种嵌套的层次呢,实际上它就不存在这种响应式的这种这种感觉了,对吧,比如说我们现在这个N的值呢,我们给它设置成五啊,那现在的话很明显,我们如果要去输出。
01:08
呃,OB勾的N属性。对吧,哎,然后哎,当然当然这块是A的B的N属性,还是N的M属性的N属性,对吧,A的M的N啊,但是这有个问题就是这里不能再重新定义这个AB了,十三三十三啊,所以咱们现在就把这个十和33去掉啊,因为你现在这个A和呃,A的值是个对象,它不是十也不是33。所以这块呢,它就有一个要改变的地方啊,这块我们要去判断这个,呃,这个参参数的个数了,所以说我们在这里,因为他只传了两个值啊,对吧,所以在这里我们就要判断一下参数的个数。就是如果你的arguments的Les啊,等于等于二的话,那我这个时候呢,就让你这个值就等于你这个对象中的本身值就可以。
02:03
啊,我们就让它等于这个对象中的这个啊呃,这个这个这个本身值就可以了,对吧,这样子来,那现在的话,我们来看一下咱们这个页面啊剩下呃,访问这个页面的话,你会发现我们现在在输出OB勾的A里的M里的N对吧,它是得五,它是有这个,但是呢,他并没有说你试图访问OB勾的A属性的M属性的,呃,就是这个属性,对吧?诶或者我把这些东西都给都给删掉。啊,你就会发现他只试图访问A属性了。啊,但是他并没有明确的告诉你,就说我们要访问M属性的N属性。对吧,就是说对这个属性的访问呢,它实际上是没有在这里体现出来的啊,因为我现在监测的是OB勾的A属性,但并没有一个循环递归的,就是说他没有在监测A的M的N,当然你现在不能这么写,因为你现在这么写的话,实际上他这么写是对的吗?啊,这么写其实。
03:03
不对啊,这么写不对,因为他们现在没有识别这个点语法的这个能力啊,所以咱们这节课呢,就需要去解决这个啊,一个对象的任何一个部分啊,都能够去进行一个。呃,循环的这样的一个监测啊,那么其实呢,就是课程到了现在就有点难度了啊,他就有点难度了,所以大家呢,就要注意啊,要呃一边听讲,然后一边写对吧?哎,是这样子的啊。好,那我们首先呢,可以把这个DeFine reactive这个函数呢,我们可以给它新建成一个文件啊。好,然后这个文件呢,默认暴露default啊这个函数。哎,它默认暴露这个函数。好,OK,那么到目前为止呢?这个函数并不需要引入谁。因为它这里头呢,都是原生JS的东西啊,我们这个对这个文件就是主文件,我们现在就需要去引入DeFine reactive。
04:08
把这个文件名复制一下吧。好,然后呢,呃,这底下就先删掉这样子的啊,就现在就要变成这个样子。好了,那接下来呢,我们为了实现能够循环递归啊,这个对象这个东西呢,我们这个时候呢,就可以给他创建一个类。那这个类呢,叫做observer,诶observer啊observer这个对类呢,就是呃,说白了它就是用来呃将一个正常的object对象转换成呢,任何属性都可以被都可以被侦测到的啊这样的一个呃一个这样的一个功能类啊,或者叫工具类啊,我们把这个新建上来,所以说这个类的名字呢,咱们就管它叫做OB observer类OB。Server。
05:00
哎,Observer类,那observer这个单词的意思是什么呢?表示的是观察啊,Observer嘛,就表示的是观察,那它就是一个就是一个起到一个观察作用的一个一个类,好,那这个类的功能我们把它写上去,就是说将一个正常的object对吧?诶然后就是转换,为什么呢?是不是转换为每个属性啊,或者说每个层级的这个属性啊,都是响应式的啊,都是响应式的就是可以被侦测的。哎,可以被侦测的这样的一个object。啊,那么这个就是咱们这个observer这个类的这样的一个,呃,一个意义,好,那他到底是怎么写呢?其实到这里的话,它就有一点点难度了啊,那咱们现在就可以去写这个observer.js咱们大写O呢,表示它是一个类,好那我们现在呢,这个东西就可以expert default。对吧,我可以默认暴露这个类class observer啊,我一写class你就知道了,我们现在是不是ES6的语法。
06:06
好,那么这个observer这个类的话,我们首先肯定是要有这个构造器,构造器的话呢,就是constructor。OK,好就OK了,那么现在呢,我们面对这个类啊,Observer这个类呢,我们。就是创建一个类,你就要想一件事。想什么事呢?对,你就要去想。这个东西到底如何被实例化?啊,就是一个类,你就马上要去想到他如何被实例化。这个大家一定要明白,那这个类如何被实例化呢?我们这个时候呢,在这个index当中呢,我们不是直接写什么东西啊,照它实例化,而是呢,我们现在呢,要这样来就先去啊,当然你先要去引入这个observer这个对象啊,当然这个observer这个对象我们肯定是要呃引入的,所以我们现在就要把它啊observer类啊,说说口误了,Observer类我们给它引进来,引进来之后呢,我们在这里继续去创建什么呢?我们在这里继续去创建这个叫欧巴。
07:12
啊,Observe这样的一个函数啊,你注意啊,这个函数的名字呢,没有R啊,它是一个函数,那这个函数是起到一个辅助判别的这么一个函数。那为什么要这样做呢?没关系,咱们慢慢的跟着老师一步一步来啊,这样的话呢,你肯定就能掌握好它,这是没有问题的啊,咱们跟着老师一步一步来,所以我们现在怎么办呢?就是我们现在就需要去写这个函数叫function啊,Function observe,好,这个函数按理说也可以放在外头。啊,也可以放到外头,但是我们就先写到主函数当中啊,写到这index当中,好,那observe的话呢,它这时候就需要有一个值传进来是value。啊,Value。好,然后我们现在就要判断,就是如果这个Y6不是对象。
08:01
啊,那这个时候就什么事都不做,就是如果啊,咱们要检测他是不是对象type of这个value啊,如果不是object啊,那么就什么都不做。哎,我们现在把这个写一下。啊,写下备注,就是如果这个value不是对象啊,那么什么都不做,也就是说呢,咱们现在这个函数它只为对象服务,咱们这个函数只为对象服务。好,然后接下来的话呢,我们干嘛对,我们在这里就可以去啊,做一个就是先定义定义咱们这个OB啊OB就一会咱们要存储observer类的实例,我们先去给它定义出来就是OB。哎,定义出来,然后这个时候呢,你看邵老师写的一个东西啊,叫做if啊,这个东西是很多的公众号,还有很多的这个,呃,文章当中其实是没有的,但是老师呢,还是觉得先把这个if写了,写什么呢?这么写就如果你这个Y6身上。
09:04
啊,咱们给他来个杠杠OB杠杠。对吧,哎,他不是安迪范的啊,他不是安迪范的好,那我这个时候OB呢,就从你这个对象身上的杠杠OB杠杠。哎,我们就取这个值。对吧,否则的话我再给他拗出来,那么拗是允许拗的,因为我已经引包了呀,然后我就把这个Y6传进去。这么来,然后我要return这个OB。好,那现在的话,这个函数就写完了。那现在这个函数写完之后,你肯定两眼一蒙,说这个杠杠OB杠杠是干什么的?别着急,你仔细阅读一下,你就会发现其中的奥秘。仔细阅读一下,有没有发现这个杠杠OB实际上就是存储observer类的实例的。对吧,那么。杠杠前缀和杠杠后缀。
10:00
意思是什么?对,意思就是我不希望它啊跟特别常见的属性重名。对吧,所以说呢,呃,包括view的底层也是使用的这个名字,就特别奇怪的一个名字叫杠杠OB杠杠。那么这个时候你要看这个Y6是什么,这个Y6是不是就是一会我们要去侦测的一个对象啊,它某种意义上讲,它就是那个data。为什么我们在这里这个东西叫value不叫data呢?这是因为这个value一会儿呢,实际上它传入它的值呢,是咱们DeFine reactive中的这个B包中的V。啊,那大家现在可能就有点儿懵了,因为老师讲这个课呢,讲过很好几年了啊,就是这个变化侦测相关的这个课程,那实际上呢,同学们到这儿就有点儿懵了,就是为什么会懵呢?原因是因为啊大家想象的不够狂野啊,不够狂野。
11:00
什么叫不够狂野呢?咱们先给大家画一张图啊,咱把这个图给大家画明白,然后估计大家就能理解了啊,就是我们现在这块不是有一个这个OB勾这个对象吗?那么这个对象的话,它的层次是挺多的啊,比如说这块还有一个B,哎,我们把这个B我们也给它放进去。对,好,给B随便赋一个值,那现在我们就要想的一个重要的事情,就是说现在到底它的底层是怎么样的一个形式啊,到底是怎么样的一个形式,那一会儿肯定我们首先最外层要干什么。最外层就是用observe,咱们刚才定义的这个小函数。Observe你没有听错,Observe这个小函数,我们要把它给observe一下,所以老师在这里帮着大家把这个流程图咱们画一下,因为很多公众号啊,包括很多的这个啊,这个博客,还有这个就是包括大家买的一些书,实际上买的那些书呢,他就是就说如果你会,你讲给已经会的人,那是可以的,但是你如果会讲给不会的,那那个人会听的很懵。
12:12
啊,所以这个时候你要记住就是它它第一步它是会看,就是看你这个最外层啊,或者说咱们一上来是要调这个OB字OB勾怎么来触发全部的东西的。那么OB observe OB勾一调用之后,下一步要干什么呢?他就会看咱们这个OB勾身上有没有啊,OB勾身上有没有杠杆OB。身上有没有杠杠OB杠杠?啊,那这块呢,是有一个箭头的,我们把箭头也画一画啊,哎,放个小烟,放个放个色是吧,漂亮一点,然后呢,这个时候的话,你就会发现它是不是没有啊,这个OB身上他没有,他一上来他当然没有了,没有的话呢,它就会怎么样对他就会拗啊,他就会拗这个欧巴滋味啊,他就会拗。
13:06
好,那拗了observer之后呢,然后干什么了,我们把这个箭头再去给它弄过来啊,再去给它竖过来。Observer,这个时候不是我拗了,拗了之后干什么?拗了之后干什么?对,拗了之后这个时候你就说老师那是不是要往他的杠杠OB身上写一个什么东西,对呀,这个OB observer这里头是干嘛,他是不是要递归了。对吧,他这个时候就要递归了,所以他这个时候呢,就相当于是需要去便利啊,便利下一层这个属性。那便利下一层属性干什么?给它设置成DeFine的。明白了吗?所以,对呀,你有没有发现我们在这里一直没有没有DeFine react的事情啊?对吧。对吧,然后逐个是不是逐个怎么着啊DeFine react。
14:03
发现了吗?就是这个图你得画出来,就现在邵老师给大家画的这个流程图,这个流程图是对于初学者而言,就是从来没有听说,从来没有听过,呃,就是数据侦测的同学而言,最重要的这么一个流程图,所以这块要便利下一层属性,然后在这里呢,要去DeFine react。好,那来了,那现在DeFine react就会被大量触发,至少A会触发一次,B会触发一次。那么在这里A会触发一次,B会触发一次干什么呢?对,它是不是就会回到observe这啊。明白吗?他又会回到这个observe这一层。看见了吗?它又会回到这个observe这一层。那你说老师这个不是死循环了吗?他不会死循环。啊,为什么不会死循环呢?因为它层数是有限的,所以他在这里呢,它就相当于是回到了这一层啊,你看在这里它就相当于又回来了啊,就走走走走走走到了这一层,那你说老师你这个图画的挺狂野啊,你这个大箭头这块回来了,但是你别忘了这块还有一些额外的过程,我还要再继续给你画。
15:14
是什么呢?就是说你别忘了,我们在范property的时候,它是不是还会有set和GET2件事?这个大家能理解对吧,那所以说他这个时候会干一个什么比较巧妙的事儿啊。对,他这个时候就会让咱们的这个就是。你想啊,我们这个函数当中,它是会,呃,就是DeFine react当中,它是不是一定一定也会去observe这一层东西,对吧?那么现在问题就是说他是不是。也有一个新的一个值,就当你调用set的时候,不是会有一个新的值进到我们的new value那个参数当中吗?你想一下,你想一下,就是我们之前在讲这个发的时候,你也知道,就是当啊,当设置啊某个属性值的时候,不是会触发。
16:08
对吧,哎,会触发什么呢?是不是会触发这个,会触发这个,呃,这个set,然后里面呢,是不是有一个叫new value啊。那你这个new value是不是也得背,也得是不是背observe啊。哦巴,Observe一下啊。看见了吗?是这样来的啊,那么现在的话,你可能说老师你现在讲完之后还是云里雾里,但是呢,我我我我跟大家说一个比较刚硬的话啊,就是你现在不管多么云里雾里,你都必须强迫自己把这个图给看懂。啊,因为很多同学学数据侦测的时候呢,他学着学着就懵了啊,那么很多同学都是在这个时候懵了。啊,都在这个时候懵了。
17:01
对吧,哎,就OK了,但是对,然后在这里呢,还需要去添加啊,别忘了逐个遍历这个,然后还需要去呃,添加这个这个属性啊,添加这个属性是在这儿,这儿new的时候就会去添加杠杠OB啊,哎,添加到杠杠OB杠杠上。啊,添加这个杠杠OB杠杠上啊是什么?就是将这个实例啊,将产生的这个实例来添加到杠杠OB杠杠上就可以了。啊,那谁的杠杠OB杠杠上就是你传进来的这个V上的吗。对吧,哎,你传进来的这个Val它上面的好,那咱们现在就仔细的再快速的去看一下这个逻辑对吧?哎,那我一上来就observe它,那他的话,他就会看他身上有没有,肯定没有啊,没有的话他就会new new的时候呢,他就会怎么着,对,他就会把实力产生到刚刚OB上,然后就会便利这一层下一层属性。对吧,那就会便利这个A和这个B,然后把这个A和这个B呢,都会进行DeFine reactive啊,都要把它变成DeFine reactive,那这个对象进B包了,就这个对象不是要进B包了吗?就是进这个VL了,然后这个B呢也进到VL那个B包了,然后这个时候的话,你要注意听,就是当某个属性值会刷set set会有new value,它这时候就会把new value over样,不过这句话现在不关键。
18:21
啊,那他这个时候呢,就又会回到这个observe上,因为你现在便利这个A,所以他就会observe它,那他身上有没有OB勾的OB呢?没有对吧,没有的话他就会扭拗的话,就会把杠口OB添加到这,然后就会变利下一层就M和N,当然了你这一层平级的还有B啊,它变利M和N之前会把B变完,也就是他变了一个顺序是OB勾这个对象,然后A,然后B,然后M,然后N。是这样子的。啊,一层一层来的,那这个时候的话,你你会你他的那个递归感其实是没有的,因为递归是自己调用自己,但是一会儿你会发现没有一个函数自己调用自己了。就是一会儿你会发现特别奇怪,就是没有一个函数自己在调用自己。
19:05
啊,这个函数呢,都是转着圈的调,转着圈的在调,所以说这个递归呢,就特别的诡异,很多同学都搞懵了啊,他是转着圈的在调,并不是真正的自己调用自己,好吧,好,那我把这个激励学完之后呢,我们就开始着手去写它。
我来说两句