JavaScript使用OLN命名空间时数组存储变量赋值后不同步更新问题
问题1解答
根本原因
你在执行concat([foo, bar])时,foo、bar尚未初始化,值为undefined。JS中所有赋值都是值传递:
- 当变量存储的是基础类型(undefined、null、数字、字符串、布尔值)时,赋值操作会直接拷贝值本身
- 只有当变量存储的是引用类型(对象、数组、函数)时,赋值操作拷贝的是指向内存中对象的引用地址
你当时往数组里存入的是undefined这个基础值的拷贝,后续给foo、bar变量赋值对象,只是让这两个变量指向了新的内存地址,和数组里已经存的undefined没有任何关联,所以数组里的值不会同步更新。
修复方案
不需要大改现有结构,只需要把要收集的变量用对象包裹一层即可,利用引用类型的特性同步更新:
- 子文件(以somefile.js为例)修改为:
// 用对象容器包裹实例,初始值设为null let foo = { dtInstance: null }; let bar = { dtInstance: null }; $(function() { console.log( " somefile.js ready!" ); mainjs.someobjects = mainjs.someobjects.concat([foo, bar]) }) // 后续初始化dataTables时,给容器的属性赋值 // 例如用户点击标签页加载完成后: foo.dtInstance = $('#table1').DataTable({ /* 你的配置 */ }); bar.dtInstance = $('#table2').DataTable({ /* 你的配置 */ });
- 后续调用adjust方法时,遍历数组判断实例存在再调用即可:
mainjs.someobjects.forEach(item => { if (item.dtInstance) { item.dtInstance.columns.adjust(); } })
问题2解答
针对dataTables列宽调整的场景,还有2种更轻量的实现方案,不需要修改你现有的命名空间结构:
- 子文件自行处理事件绑定:每个子文件里的表格主动监听标签页的显示事件,触发时直接调整自身列宽。比如使用Bootstrap标签页的场景,代码示例:
// 直接写在对应子文件里即可 $('a[data-bs-toggle="tab"]').on('shown.bs.tab', function (e) { // 判断当前激活的是当前表格所属的标签页 if ($(e.target).attr('href') === '#your-tab-id') { // 表格已初始化的话直接调用adjust if ($.fn.DataTable.isDataTable('#table1')) { $('#table1').DataTable().columns.adjust(); } } })
这种方案耦合度最低,每个文件只负责自己的逻辑,不需要把实例统一收集到mainjs,也不需要修改现有结构。
- 全局自定义事件通知:main.js在监听到标签页切换时,触发一个全局自定义事件,各个子文件监听该事件,判断自身表格需要调整时执行对应逻辑即可,比统一维护实例数组的扩展性更好。
内容的提问来源于stack exchange,提问作者logicOnAbstractions
相关产品推荐
相关产品推荐

