我们可以看一下ES3的定义, ES5的定义是有变动的。
The delete Operator The production UnaryExpression : delete UnaryExpression is evaluated as follows: 1. Evaluate UnaryExpression. 2. If Type(Result(1)) is not Reference, return true. 3. Call GetBase(Result(1)). 4. Call GetPropertyName(Result(1)). 5. Call the [[Delete]] method on Result(3), providing Result(4) as the property name to delete. 6. Return Result(5).我简单翻译一下,可能不太正确哈:
执行一元表达式
如果第一步返回的未被引用,返回真
console.log(delete xxxxxxxxxx) //true console.log(delete "a") // true console.log(delete {a:1}) // true console.log(delete 1) // true取到对象
取属性名
用第四步获得的属性名,在第三步返回的结果上进行删除操作
返回第五步返回的结果。
这里的Resuslt(1)本身应该不是数据本身,类似一个引用地址吧。
小结一下delete 返回false, 一定是没删除成功
delete 返回true, 不一定删除成功
所以,delete返回true,最好自己再动手检查一下。万无一失。
额,我是不是跑题了,今天的主题,不是告诉你如何使用delete,而是谨慎用delete。
比较一下性能我们先创建1万个对象,每个对象都有p0到p24 一共25个属性。
然后我们按照一定的规则删除属性和设置属性为undefined。
我们记录了大约五次执行事件对比。
可以看出来delete 时间不稳定,而且性能低不少。
到这里,我们还不要惊讶。看我稍微改动一下代码:
function createObjects(counts = 10000) { var arr = []; for (let i = 0; i < counts; i++) { const obj = {}; // for (let j = 0; j < pcounts; j++) { // obj[`p${j}`] = `value-${i}-${j}`; // } arr.push({ 0: `value-${i}-0`, 1: `value-${i}-1`, 2: `value-${i}-2`, 3: `value-${i}-3`, 4: `value-${i}-4`, 5: `value-${i}-5`, 6: `value-${i}-6`, 7: `value-${i}-7`, 8: `value-${i}-8`, 9: `value-${i}-9`, 10: `value-${i}-10`, 11: `value-${i}-10`, 12: `value-${i}-10`, 13: `value-${i}-10`, 14: `value-${i}-10`, 15: `value-${i}-10`, 16: `value-${i}-10`, 17: `value-${i}-10`, 18: `value-${i}-10`, 19: `value-${i}-10`, 20: `value-${i}-10`, 21: `value-${i}-10`, 22: `value-${i}-10`, 23: `value-${i}-10`, 24: `value-${i}-10` }); } return arr; } const arr = createObjects(); const arr2 = createObjects(); console.time("del"); for (let i = 0; i < arr.length; i++) { const rd = i % 25; delete arr[i][rd] } console.timeEnd("del"); console.time("set"); for (let i = 0; i < arr2.length; i++) { const rd = i % 25; arr2[i][rd] = undefined; } console.timeEnd("set"); // del: 1.44189453125 ms // set: 2.43212890625 ms // del: 1.737060546875 ms // set: 3.10400390625 ms // del: 1.281005859375 ms // set: 2.85107421875 ms // del: 1.338134765625 ms // set: 1.877197265625 ms // del: 1.3203125 ms // set: 2.09912109375 ms到这里,画风一转。 del居然比set还快了。。。。。。
而set的速度实际基本没有什么变化。
这里就要提出几个概念:
常规属性 (properties) 和排序属性 (element)。
上面的代码变化不多,就是属性名称从p0格式修改为了0格式。
p0正式常规属性,0是排序属性。
对象中的数字属性称为排序属性,在 V8 中被称为 elements。