JavaScript删除对象属性:delete与解构的副作用及Vue响应式处理

作者:青山有信时间:2026-10-24 17:33:24浏览:440

本文对比了JavaScript中删除对象属性的两种常用方式:delete/deleteProperty与解构赋值。重点分析了delete操作对原始对象引用的副作用,以及在Vue等MVVM框架中可能引发的响应式丢失问题。通过示例展示了如何利用解构保留原数据,并提供了Vue中确保视图更新的正确删除方法。

Thinking系列,旨在利用10分钟的时间传达一种可落地的编程思想。

在前端业务开发中,常需将后端返回的接口数据存入对象。为了前端交互便利,可能会在对象中临时增加额外属性。但在提交数据给后端时,这些前端特有的属性并无意义,因此需要在保存前将其剔除。

真实业务场景中,通常在数据提交前需要移除特定的 *Value  字段。


async saveData (type, data) {
  // 提交时删除多余字段
  delete data.isCommonValue
  delete data.isRemoteValue
  await this.$request({
    ...API.EDIT_SERVICE,
    method: type === 'add' ? 'post' : 'put',
    data
  })
}

上述做法是常见的处理逻辑,但在某些特定场景下,它并非最优解,甚至可能引入副作用。下文将通过具体示例进行说明。

示例演示

为了更清晰地展示上述情况,我们重新构建一个简化示例(仅用于说明实现原理)。


let person = {
  id: '001',
  name: 'ligang', 
  email: 'xxx@x.com'
}

具体需求:在将数据提交给后端之前,必须移除 email 字段。

方法一:使用 delete 关键字

这与前文提到的业务代码处理方式类似。


delete person.email
console.log(person)	// {id: '001', name: 'ligang'}

需要注意的是,原数据中的相关属性也会被直接删除。

Reflect.deleteProperty()  同样可用于删除属性,其效果与上述 delete 行为一致。


Reflect.deleteProperty(person, 'email')

方法二:使用解构赋值

通过解构生成新对象,从而避免对原始对象引用产生副作用。


let {id, name} = person
let newPerson = {id, name}
console.log(newPerson) // {id: '001', name: 'ligang'}

此方法会切断与原数据的引用关系。当需要保留的属性较少时,这种方式处理简单且易于理解;但若需保留的属性过多,则代码会变得复杂。


let {email, ...newPerson} = person
console.log(newPerson) // {id: '001', name: 'ligang'}

同样会切断与原数据的引用。当需要保留的属性较多时,这种方式处理简单且易于理解;但若需保留的属性过少,则代码会变得复杂。

补充说明

对于已创建的 Vue 实例,不允许动态添加根级别的响应式属性。以下尝试均无效:


this.$set(this, 'email', '')
this.$set(this.$data, 'email', '')

总结与建议

在实际使用中,强烈建议采用方式二(解构)进行操作,以不影响原始数据。特别是在 MVVM 框架中,原始数据通常是响应式的,使用 delete/deleteProperty  会切断“响应关系”,导致 delete 操作后的数据响应出现异常。

示例演示


data () {
  return {
    person: {
      name: 'ligang',
      email: 'x@x.com'
    }
  }
},
methods: {
	deleteProp () {
  	delete this.person.email
    // this.$delete(this.person, 'email')
	},
  addProp () {
  	this.person.email = 'xxx'
    this.$set(this.person, 'address', 'xxx')
  }
}

1. 执行 delete  操作后,JS 对象属性虽被剔除,但页面可能未及时响应。此时可使用 Vue 中的 this.$delete() 确保删除操作能触发视图更新。

2. 执行 add  操作,重新添加 email 及 address 属性。

1. this.person.email = 'xxx'  并不具备响应式

2. this.$set(this.person, 'address', 'xxx')  具备响应式

本文到此结束,希望能对您有所帮助,也欢迎持续关注本站获取更多内容!

作者最新文章