如何从JavaScript对象中移除属性
技术背景
在JavaScript编程中,经常需要对对象的属性进行操作,移除对象的属性是其中常见的需求。对象在JavaScript里可看作键值对的映射,移除属性就是移除这些键值对。
实现步骤
使用delete
关键字
- 直接删除属性:可以使用
delete
关键字直接从对象中移除属性。示例代码如下:
1 2 3 4 5 6 7
| const myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; delete myObject.regex; console.log(myObject);
|
- 动态删除属性:通过变量动态指定要删除的属性。示例代码如下:
1 2 3 4 5 6 7 8
| const myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; const prop = "regex"; delete myObject[prop]; console.log(myObject);
|
使用对象解构
- 创建新对象并移除指定属性:使用ES6的对象解构和剩余参数语法,创建一个不包含指定属性的新对象,同时保留原对象不变。示例代码如下:
1 2 3 4 5 6 7 8
| const myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; const { regex, ...newObj } = myObject; console.log(newObj); console.log(myObject);
|
- 重新赋值给原变量:若要将移除属性后的对象重新赋值给原变量,可使用
let
声明变量。示例代码如下:
1 2 3 4 5 6 7
| let myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; ({ regex, ...myObject } = myObject); console.log(myObject);
|
使用Array#reduce
方法
- 修改原对象:使用
reduce
方法遍历对象的键,将不需要删除的键和对应值添加到新对象中,最后将新对象赋值给原对象。示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12
| const myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; myObject = Object.keys(myObject).reduce((obj, key) => { if (key !== "regex") { obj[key] = myObject[key]; } return obj; }, {}); console.log(myObject);
|
- 创建新对象:将
reduce
方法的结果赋值给新变量,避免修改原对象。示例代码如下:
1 2 3 4 5 6 7 8 9 10
| const myObject = { ircEvent: 'PRIVMSG', method: 'newURI', regex: '^http://.*', }; const myNewObject = Object.keys(myObject).reduce((obj, key) => { key !== 'regex' ? obj[key] = myObject[key] : null; return obj; }, {}); console.log(myNewObject);
|
使用第三方库
- Lodash的
omit
方法:使用Lodash
库的omit
方法可以方便地移除对象的指定属性。示例代码如下:
1 2 3 4
| import omit from 'lodash/omit'; const prevObject = {test: false, test2: true}; const nextObject = omit(prevObject, 'test2'); console.log(nextObject);
|
- Ramda的
dissoc
和omit
方法:使用Ramda
库的dissoc
和omit
方法也能实现移除对象属性的功能。示例代码如下:
1 2 3 4 5 6 7 8 9 10
| const R = require('ramda'); const myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; const newObject = R.dissoc('regex', myObject); console.log(newObject); const result = R.omit(['ircEvent', 'regex'], myObject); console.log(result);
|
核心代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| const myObject1 = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; delete myObject1.regex; console.log(myObject1);
const myObject2 = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; const { regex, ...newObj2 } = myObject2; console.log(newObj2);
const myObject3 = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; const myNewObject3 = Object.keys(myObject3).reduce((obj, key) => { key !== 'regex' ? obj[key] = myObject3[key] : null; return obj; }, {}); console.log(myNewObject3);
import omit from 'lodash/omit'; const prevObject = {test: false, test2: true}; const nextObject = omit(prevObject, 'test2'); console.log(nextObject);
const R = require('ramda'); const myObject4 = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; const newObject4 = R.dissoc('regex', myObject4); console.log(newObject4); const result4 = R.omit(['ircEvent', 'regex'], myObject4); console.log(result4);
|
最佳实践
- 性能考虑:若要操作大量对象,
delete
操作性能不佳,可考虑使用对象解构或第三方库方法。 - 避免副作用:若不希望修改原对象,可使用对象解构或第三方库方法创建新对象。
- 检查属性是否存在:在使用
delete
移除属性前,可先检查属性是否存在,避免潜在错误。示例代码如下:
1 2 3 4 5 6 7 8 9
| const obj = { "property": "value", "property2": "value" }; if (obj && obj.hasOwnProperty("property2")) { delete obj.property2; } else { }
|
常见问题
delete
操作与设置属性为null
或undefined
的区别
delete
操作会从对象中移除属性本身,而将属性值设置为null
或undefined
只是改变了属性的值,属性仍然存在于对象中。示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12
| const obj = { myProperty: 1 }; console.log(obj.hasOwnProperty('myProperty')); delete obj.myProperty; console.log(obj.hasOwnProperty('myProperty'));
const obj2 = { myProperty: 1 }; obj2.myProperty = null; console.log(obj2.hasOwnProperty('myProperty'));
|
使用delete
操作数组元素的问题
使用delete
操作数组元素会在数组中留下“空洞”,不会更新数组的length
属性,也会影响数组的索引。若要移除数组元素,建议使用Array#splice
或Array#pop
方法。示例代码如下:
1 2 3 4 5
| const arr = [0, 1, 2, 3, 4]; delete arr[2]; console.log(arr); arr.splice(3, 1); console.log(arr);
|
不可配置属性的删除问题
使用delete
或Reflect.deleteProperty
方法无法删除不可配置的属性,如使用Object.freeze
或Object.seal
处理过的对象属性。示例代码如下:
1 2 3 4
| let obj = Object.freeze({ prop: "value" }); let success = Reflect.deleteProperty(obj, "prop"); console.log(success); console.log(obj.prop);
|