JS中实现全局数据对象
全局是一个范围概念,可以是整个页面的全局,也可以是针对某个组件数据实例的全局,我们一定要明确这个范围边界,否则会出现变量污染的问题。
一个变量污染的案例
我写了一个折线图的组件,由于折线图其实是由很多子元素(比如坐标轴、线条、tooltip等)构成的,每个子元素都是一个独立的类,而这些类都需要用到用户的配置项(比如样式等),因此我需要一个数据对象,可以在不同的子组件之间应用,将这些用户配置传递过去。
我初始构想的,就是通过定一个全局的module来传递数据,然后我就这样写了:
全局数据对象的模块(state.js):
1 | |
修改数据(line.js):
1 | |
使用修改后的数据(tooltip.js):
1 | |
这样在页面只有一个图的时候是没问题的,但是当用户想绘制多个图的实例时,就出问题了:第一个图修改的数据,会在第二个图中生效。
原因是这个state模块,是针对代码层面的全局,也就是相当于挂载到window对象上的全局,而我们预期的,其实应该是仅针对图形实例的生命周期生效。
所以后来我重构了代码,改成了每次初始化实例时,都是使用state的深克隆对象,并将其以构造函数参数的形式传递给子组件:
组件的构造函数(line.js):
1 | |
子组件(tooltip.js):
1 | |