欢迎各位兄弟 发布技术文章
这里的技术是共享的
如何移除一个JavaScript对象?
首先分析问题:
再由具体到抽象,尝试三个层面来解决这个问题:
根据ECMAScript中对JSON对象的定义,它只有两个方法:parse() && stringify()
,放弃。
根据ECMAScript的Working with Objects,文档倒数第二小节正好讲得就是Deleting properties:
可以使用
delete
运算符来删除一个对象的非继承属性。
因此,我们就从delete
运算符入手。
来看看delete
运算符的定义:
delete
运算符用来删除一个对象、一个对象属性或者数组中的某个元素。
示例:
delete objectName;
delete objectName.property;
delete objectName[index];
delete property; // legal only within a with statement
delete
还能用来删除一个全局变量,如果该变量不是使用var
声明的。(区分variable declaration和property assignment)
示例:
var GLOBAL_OBJECT = this;
/* create global property via variable declaration; property has DontDelete */
var foo = 1;
/* create global property via undeclared assignment; property has no DontDelete */
bar = 2;
console.log(foo);
delete foo; // false
console.log(typeof foo); // "number"
console.log(bar);
delete bar; // true
console.log(typeof bar); // "undefined"
如果delete
操作成功,它将会把操作数的值置为undefined
,然后返回true
。否则返回false
。
注意,使用delete
删除一个数组array的元素i后,array[i]元素就不存在了。
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
delete trees[3];
if (trees[3] || 3 in trees) { // undefined || false
// this does not get executed
}
因此,如果你只是想删除array[i]的值,同时保持i元素在array中的位置,就不能使用delete
,而应该直接对array[i]赋值。
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
trees[3] = undefined;
if (trees[3] || 3 in trees) { // undefined || true
// this gets executed
}
因为delete
操作的效率很低。
delete
很慢因为JavaScript语言的动态属性:
可以随时随地向对象添加、删除属性。
因此大多数JavaScript引擎对Object的实现时,采用的是dictionary-like data structure,比如hashmap
。采用这种数据结构的一大弊端就是dictionary lookup是非常低效的,即读取速度慢。
为了提高读取对象属性的速度,V8引擎使用了hidden class技术,其基本思想就是:空间换时间。
V8 hidden class的具体细节,请参考:Fast Property Access - V8 Design
注意第三条,每次增加或删除属性的操作,都会引发hidden class transition。如果一个对象的属性很多,那么这个transition操作将会很耗资源。
而JavaScript的prototype继承机制,使得对象属性的数量很容易就达到较大的数字。因此,尽量避免使用delete
。
与delete
类似的方案是undefined/null
的赋值操作。
根据它们的性能对比测试可以看出,使用undefined/null
的赋值操作的效率,是delete
操作的十倍以上。对于一些计算密集的算法,尤其需要注意。
来自 https://github.com/simongong/js-stackoverflow-highest-votes/blob/master/questions1-10/remove-propert...