- Published on
5分钟速读系列-提供者模式/原型模式
- Authors
- Name
- noodles
- 每个人的花期不同,不必在乎别人比你提前拥有
这个系列是Improve how you architect webapps上文章的读书笔记。
提供者模式
提供者模式通过封装方法给予应用订阅不同数据源的能力。react中通过外层的Provider来提供全局的store,在组件内部通过useContext来获取相关的Context值。
// 根组件通过Provider的value绑定全局store
export const ThemeContext = React.createContext();
const themes = {
light: {
background: "#fff",
color: "#000"
},
dark: {
background: "#171717",
color: "#fff"
}
};
export default function App() {
const [theme, setTheme] = useState("dark");
function toggleTheme() {
setTheme(theme === "light" ? "dark" : "light");
}
const providerValue = {
theme: themes[theme],
toggleTheme
};
return (
<div className={`App theme-${theme}`}>
<ThemeContext.Provider value={providerValue}>
<Toggle />
</ThemeContext.Provider>
</div>
);
}
// Toggle组件
import React, { useContext } from "react";
import { ThemeContext } from "./App";
export default function Toggle() {
const theme = useContext(ThemeContext);
return (
<label className="switch">
<input type="checkbox" onClick={theme.toggleTheme} />
</label>
);
}
在React应用中通过全局的context可以解决组件属性的传递问题,便于组件的设计。但是全局Context的更新会导致消费对应Context组件的更新,造成需要不必要的渲染。这里就需要对全局Context进行更细粒度的拆分。
原型模式
JavaScript通过原型完成对象间属性的共享。通过原型能减少相同属性或者方法的创建,相同类型的实例可以共享实例原型上的属性和方法。对于原型模式需要理解几下的几点:
- 实例对象的__proto__指向构造函数的prototype(实例与原型的关系).构造函数的prototype的constructor(构造函数与原型的关系).
class Dog {
constructor(name) {
this.name = name;
}
bark() {
return `Woof!`;
}
}
const dog1 = new Dog("Daisy");
dog1.__proto__ === Dog.prototype // true
Dog.prototype.constructor === Dog // true
对象属性的获取是顺着对象__proto__沿着原型链查找,会一直查找到Object.prototype(Object.prototype.__proto__是null)
理解new关键字中原型的处理方式,new操作符主要做了如下的操作:
- 以构造器的原型为属性创建新对象
- 将新对象作为this调用构造器
- 如果构造器返回的是对象则返回否则返回第一步创建的对象
function myNew(Con, ...args) {
const obj = Object.create(Con.prototype);
const ret = Con.call(obj, args);
if(ret instanceof Object && ret !== null) {
return ret;
}
return obj;
}