logo
Published on

如何从JavaScript对象中移除属性?

Authors
  • Name
    Twitter

在JavaScript中,我们常常需要对对象进行操作,例如添加、更新或删除属性。其中,删除属性是一个常见的需求。这篇文章将详细介绍如何从JavaScript对象中移除属性,并讨论相关的细节和注意事项。

使用 delete 操作符

delete 操作符用于从对象中移除属性。例如:

const obj = { foo: 'bar' }
delete obj.foo
console.log(obj.hasOwnProperty('foo')) // false

注意,对于数组来说,删除操作和移除元素是不同的。为了从数组中移除元素,请使用 Array#spliceArray#pop。例如:

let arr = [0, 1, 2, 3, 4]
arr.splice(3, 1) // 删除第三个元素
console.log(arr) // [0, 1, 2, 4]

详细解释

严格来说,在JavaScript中不可能真正删除任何东西。delete 操作符既不会删除对象,也不会释放内存。它的作用是将操作数设为 undefined 并操纵父对象,使该成员消失。

let parent = {
  member: { str: 'Hello' },
}
let secondref = parent.member

delete parent.member
console.log(parent.member) // undefined
console.log(secondref) // { str: "Hello" }

对象本身没有被删除,只是引用被移除了。当所有对对象的引用都被移除后,内存才会被垃圾回收机制回收。

delete 对数组的影响

需要注意的是,delete 操作符不会为你重新组织数据结构,这可能会产生一些看似反直觉的结果。删除数组索引时,会在数组中留一个"空洞"。

let array = [0, 1, 2, 3]
delete array[2]
console.log(array) // [0, 1, empty, 3]

这是因为数组本质上是对象,索引就相当于键。

let fauxarray = { 0: 1, 1: 2, length: 2 }
fauxarray.__proto__ = [].__proto__
fauxarray.push(3)
console.log(fauxarray) // [1, 2, 3]
console.log(Array.isArray(fauxarray)) // false
console.log(Array.isArray([1, 2, 3])) // true

JavaScript内置的不同函数对处理带有空洞的数组有不同的方式。

举例说明:

let array = [1, 2, 3]
delete array[1]
console.log(array) // [1, empty, 3]
console.log(array.map((x) => 0)) // [0, empty, 0]

因此,delete 操作符不适合用于从数组中移除元素。数组有专门的方法来移除元素和重新分配内存:Array#splice()Array#pop

Array#splice

Array#splice 会修改数组,并返回任何被删除的元素。参数 deleteCount 指定从指定位置开始删除的元素个数,其后的参数可用于插入新元素。

let a = [0, 1, 2, 3, 4]
console.log(a.splice(2, 2)) // [2, 3]
console.log(a) // [0, 1, 4]

Array#slice

Array#slice 不会修改原始数组,会返回一个新的数组,包含从 startend 指定的索引元素。

let a = [0, 1, 2, 3, 4]
let slices = [a.slice(0, 2), a.slice(2, 2), a.slice(2, 3), a.slice(2, 5)]

console.log(slices)
// [ [0, 1], [], [2], [2, 3, 4] ]

Array#pop

Array#pop 移除数组的最后一个元素,并返回该元素,数组的长度因此减一。

Array#shift

Array#shift 类似于 pop,只是它移除的是数组的第一个元素,操作后的数组会向前移动一个位置。