在 JavaScript 中,移除对象中的属性是一项常见的操作。本文将详细介绍如何使用 delete
操作符以及其他相关方法。
使用 delete
操作符
delete
操作符用于从对象中移除属性。例如:
const obj = { foo: "bar" };
delete obj.foo;
console.log(obj.hasOwnProperty("foo")); // false
需要注意的是,对于数组来说,使用 delete
并不意味着移除某个元素。要移除数组中的一个元素,可以使用 Array#splice
或 Array#pop
方法。例如:
let arr = [0, 1, 2, 3, 4];
arr.splice(3,1); // 移除第3个元素
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
操作符不会为你重新组织数据结构。例如,当删除数组索引时,会留下一个“空洞”:
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 中不同的内置函数在处理带有“空洞”的数组时行为不同:
for..in
语句会完全跳过空索引。- 传统
for
循环会在该索引处得到undefined
。 - 使用
Symbol.iterator
的任何方法会返回该索引处的undefined
。 forEach
、map
和reduce
会跳过缺失的索引,但不会移除它。
例如:
let array = [1, 2, 3];
delete array[1];
console.log(array.map(x => 0)); // [0, empty, 0]
因此,对于移除数组中的元素这种常见情况,不应该使用 delete
操作符。数组有专门的移除元素并重新分配内存的方法:Array#splice()
和 Array#pop
。
Array#splice 方法
Array#splice(start[, deleteCount[, item1[, item2[, ...]]]])
Array#splice
会修改数组并返回移除的元素。deleteCount
个元素从索引 start
开始移除,并且 item1, item2...itemN
会从索引 start
开始插入到数组中。如果省略 deleteCount
,则会移除从 startIndex
开始的所有元素直到数组结束。
let a = [0, 1, 2, 3, 4];
let removed = a.splice(2, 2);
console.log(removed); // [2, 3]
console.log(a); // [0, 1, 4]
Array#slice 方法
Array#slice([begin[, end]])
Array#slice
是非破坏性的,返回一个包含从 start
到 end
索引的新的数组。如果未指定 end
,则默认为数组的末尾。end
是一个负数时,表示从数组末尾向前计算的索引。如果 end <= start
,结果是一个空数组。
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
会移除数组的最后一个元素并返回该元素。这个操作改变了数组的长度。与之相对的是 push
。
let a = [1, 2, 3];
let lastElement = a.pop();
console.log(lastElement); // 3
console.log(a); // [1, 2]
Array#shift 和 Array#unshift 方法
Array#shift
类似于 pop
,它移除的是数组的第一个元素。与之相对的是 unshift
。
let a = [1, 2, 3];
let firstElement = a.shift();
console.log(firstElement); // 1
console.log(a); // [2, 3]
通过本文,你应该已经掌握了如何从 JavaScript 对象或数组中移除属性或元素的方法。希望这些技巧能帮助你在日常开发中更加高效地操作数据结构。