2.4.1 闭包和单例
在2.1.1节我们用闭包实现了单例。单例是前端开发经常用到的模式,前端使用单例实现React等框架中的全局变量和服务,如代码清单2-9所示。
代码清单2-9 闭包和单例实现彩蛋功能
// 1 使用单例服务的全局变量展示彩蛋数量 // services/config.js const Singleton = function(easterEggsCount) { this.storeEasterEggsCount = easterEggsCount; } Singleton.getInstanceEasterEggsCount = (function(){ var instance; return function() { if (!instance) { instance = new Singleton(1); } else { instance.storeEasterEggsCount += 1; } return instance.storeEasterEggsCount; } })(); global.constants = { getEasterEggsInstatnce: Singleton.getInstanceEasterEggsCount() appname: 'breakthrough', }; // 调用彩蛋功能方法,省略业务逻辑 // pages/overview/OverviewEvaluation.js import React from 'react' import '@/services/config'; class OverviewEvaluation extends React.Component { render() { return ( <div className="over-view-e-page"> { global.constants.getEasterEggsInstatnce } </div> ) } } export default OverviewEvaluation // 2 使用React支持的Context完成类似功能 // pages/easterEggs/EasterEggsCountContext.js import React, { createContext } from 'react' const EasterEggsCountContext = createContext(); export default EasterEggsCountContext; // 外层代码,生成全局数据 // pages/OverviewPage.js import React, { createContext } from 'react' import EasterEggsCountContext from './easterEggs' // 省略业务代码 class OverviewPage extends React.Component { constructor(props) { super(props); this.state = { easterEggsCount: 0 } this.increaseEasterEggsCount = this.increaseEasterEggsCount.bind(this) } increaseEasterEggsCount() { if (100 * Math.random() > 95) { this.setState({ easterEggsCount: _easterEggsCount + 1 }) } } render() { const _easterEggsCount = this.state.easterEggsCount return ( <EasterEggsCountContext.Provider value={ _easterEggsCount }> <div className="over-view-page" onClick={this.increaseEasterEggsCount}> // 省略业务代码 </EasterEggsCountContext.Provider> ) } } export default OverviewPage // 子组件,使用全局数据 // pages/overview/OverviewLink.js import React from 'react' import EasterEggsCountContext from '../easterEggs' class OverviewLink extends React.Component { render() { return ( <EasterEggsCountContext.Customer> { easterEggsCount => ( <div className="over-view-l-page"> { easterEggsCount } </div> ) } </EasterEggsCountContext.Customer> ) } } export default OverviewLink