js 数组清空 最快的方法
发布于 7 年前 作者 1160007652 5958 次浏览 来自 分享

今天看设计模式书,学习到的。分享在此!

let arr = [1,2,3,4,5]; console.log(arr); arr.length=0; console.log(arr);

23 回复

arr = []; 速度也很快。

来自酷炫的 CNodeMD

arr=null; 彻底

这应该不是最快的,length毕竟还是要计算数组的长度的,直接清空就少了计算长度的步骤

来自酷炫的 CNodeMD

如果 这种效果 呢 – arr.length = 2; 保留2个数组元素

@mrxf @xiaozhouge 赋值会造成变量引用就变了吧

来自 CNodeMD

arr.length=0;清空最快?哪本书说的?

一般都是等于[]

最快和最慢都得看引擎实现,还有至于清空数组的方法,看场景吧:

var foo = [1,2,3]; var bar = [1,2,3]; var foo2 = foo; var bar2 = bar; foo = []; bar.length = 0; console.log(foo, bar, foo2, bar2);

// [] [] [1, 2, 3] []

在vue里这种方式无效

来自酷炫的 CNodeMD

当你试图给Array设置一个更小的length时,会循环令length - 1并删除该位置的属性直到数组长度减少到指定长度

const arr = [1, 2, 3, 4, 5];
arr.length = 1;
arr[2]; // undefined
arr; // [1]

然而 non-configurable 的属性依然是无法删除的,然后arr.length的减少会在这个位置停下

const arr = [1, 2, 3, 4, 5];
Object.defineProperty(arr, 2, {configurable:false});
arr.length = 1;
arr[2]; // 3
arr; // [1, 2, 3]
arr.length; // 3

(ES8标准 22.1.4.1 和 9.4.2.4 两节)
9.4.2.4.16

  • Repeat, while newLen < oldLen,
    • Set oldLen to oldLen - 1.
    • Let deleteSucceeded be ! A.[[Delete]](! ToString(oldLen)).
    • If deleteSucceeded is false, then
      • Set newLenDesc.[[Value]] to oldLen + 1.
      • If newWritable is false, set newLenDesc.[[Writable]] to false.
      • Let succeeded be ! OrdinaryDefineOwnProperty(A, “length”, newLenDesc).
      • Return false.

用js代码来模拟这个过程的话,就是

function arraySetLength(arr, newLen) {
  // ...
  let oldLen = arr.length;
  while (newLen < oldLen) {
    oldLen--;
	const deleteSucceeded = Reflect.deleteProperty(arr, oldLen);
	if (deleteSucceeded === false) {
	  arr.length = oldLen + 1; // 这里视为单纯的设置arr的length属性
	  // ...
	  return false;
	}
  }
  // ...
  arr.length = newLen; // 这里视为单纯的设置arr的length属性,实际上这一行是放在上面的循环前先执行的
  return true;
}

另外, image.png (10元素的数组,删除9个。chrome 65。把pop改成循环方式几乎不影响结果,在本例中甚至连shift9次的操作都比setLength快一点,不过使用splice(0, 1)方式的速度要慢一些)

果然- 一波类似 php是最好的语言,能激起一股 学术氛围

arr.length=0;

坑级代码。

@dbit-xia 对,确实变了。但是之前的就会被回收了,并没有问题。而且速度够快。

来自酷炫的 CNodeMD

有没有什么方法能够测试哪种方法最快?

回到顶部