前言
最近每天学的都是些查缺补漏的知识,深度一般广度到不少,因此用这样的方式做个每日总结感觉还不错,今天主要写三个东西,一个是偶然看到的易混点,一个是发布订阅模式与Vue的结合问题,还有就是一次nice的面试收获。
怎么理解React没有实现数据双向绑定
首先React不是一个MVVM框架,他只是一个View层的库,而View层的数据渲染,即简单的props和state,并不需要双向绑定也能满足基本需求,所以它并不是不能做,只是没必要做。
那React怎么实现的状态改变之后,视图也更新了呢?比较简单的理解就是通过重新渲染,React是不会主动监听视图的变化的,每次渲染组件就是一个全新的状态,不追踪原来的变化,也就谈不上数据绑定的实现。对于Input组件这种需要依赖数据变化的场景,则使用类似操作DOM的场景,利用合成事件手动通知状态的改变。
如果还不理解的话,这篇文章个人感觉还不错。
综上,在React,实现数据的双向绑定是通过受控组件完成的,这也是React官方推荐的方式。
观察者模式
正在看这个的时候撇了一眼手机,接到了阿里爸爸的电话,,,
这差不多是前端领域使用最多的设计模式了,可以拿出来说的也有很多,典型的就有Vue的响应式原理,全局事件总线等。
关于Vue的响应式原理,官网有详细的讲解,这里简单的说一下,首先利用Proxy或Object.defineProperty生成的Observer既充当了监听器的作用,又充当发布者的角色,在数据属性变化后来通知订阅者;同时Compile解析模板中的指令,收集指令依赖的方法和数据,等待数据变化后的渲染;最后watcher连接两者,使得订阅依赖的数据变化转化为视图的变化。
插句话,Proxy优化了Object.defineProperty对于新增属性不被拦截、不需要遍历对象属性进行修改等问题,在immer这样的库中也得到了广泛使用。
准确的说,Vue实现了观察者模式,微微区别于发布订阅模式的一点,所有的操作都需要经过事件中心去完成,这里写一个简单的Event Bus
class Event {
constructor() {
this.handlers = {};
}
on(event, cb) {
if (!this.handlers[event]) {
this.handlers[event] = [];
}
this.handlers[event].push(cb);
}
emit(event, ...args) {
if (this.handlers[event]) {
this.handlers[event].forEach(callback => {
callback(...args);
});
}
}
off(event, cb) {
const callbacks = this.handlers[event];
const index = callbacks.indexOf(cb);
if (index !== -1) {
callbacks.splice(index, 1);
}
}
once(event, cb) {
const wrapper = (...args) => {
cb.apply(...args);
this.off(event, wrapper);
};
this.on(event, wrapper);
}
}
一次nice的interview
点赞alipay的大佬,整个过程都有帮助解答,收获很多,感觉部分东西要抽一天来消化一下,这里大致提一下,各种CSS方案解决作用域问题的解决原理,IFC之类的问题,图层之类的问题,polyfill的实现,hidden_class等,呼~加上算法题,有够折腾的了。