如何优化jQuery中HTML data-*属性存储对象的键值扩展操作
问题成因
你使用$.extend时出现所有.record的data-update同步更新的问题,核心是JS对象的引用共享:
- 如果你初始化所有
.record的data-update属性时,直接给所有元素赋值了同一个对象(例如$('.record').data('update', {})),由于对象是引用类型,所有元素的data('update')实际指向内存中的同一个对象。你调用$.extend修改该对象时,所有持有该引用的元素的data值都会同步变化。 - 如果未提前初始化
data-update属性,第一次调用$record.data('update')会返回undefined,也会导致$.extend的操作逻辑异常,出现意外的引用共享。
可行解决方案
第一步:修正初始化逻辑
给每个.record单独创建独立的空对象,从根源避免引用共享:
$('div.record').each(function() { // 每个元素单独创建新对象,互不干扰 $(this).data('update', {}); })
第二步:简化更新逻辑
你完全不需要重新给data-update赋值整个新对象,直接修改已存储对象的属性即可,写法比展开运算符更简洁:
// 改用事件委托,性能更优,动态新增的record也无需重新绑定事件 $('form.crud, table.crud').on('change', '.crud-control', function() { const $record = $(this).closest('.record'); // 直接修改已存储对象的属性,自动同步到data中,无需重新赋值 $record.data('update')[this.name] = this.value; });
以上写法完全等效于你原来的展开运算符写法,代码量更短,可读性也更高。
如果你仍想使用$.extend,在完成第一步初始化的前提下,该写法也可以正常工作,不会再出现批量更新的问题:
$.extend($record.data('update'), {[this.name]: this.value});
内容的提问来源于stack exchange,提问作者Dirk Albrecht
相关产品推荐
相关产品推荐

