CNode

js 数组清空 最快的方法

分享
11160007652发布于8 年前最后回复8 年前23 回复6829 浏览0 收藏

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

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

查看回复

回复 (23)

H
hlj2722#1·8 年前

学习

M
mrxf#2·8 年前

arr = []; 速度也很快。

来自酷炫的 CNodeMD

X
xiaozhouge#3·8 年前

arr=null; 彻底

E
entrehuihui#4·8 年前

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

来自酷炫的 CNodeMD

1
1160007652#5·8 年前

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

D
dbit-xia#6·8 年前

来自 CNodeMD

D
dbit-xia#7·8 年前
引用 xiaozhougearr=null; 彻底

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

来自 CNodeMD

C
chapgaga#9·8 年前

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

F
FourLeafClover#10·8 年前
F
FourLeafClover#11·8 年前

@chapgaga 我一般是直接赋值[]
【来自酷炫的小程序】

W
wwdDongDong#12·8 年前

一般都是等于[]

D
dengnan123#13·8 年前

[]

G
ghostcode#14·8 年前

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

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] []

Z
zhangmingfeng#15·8 年前

在vue里这种方式无效

来自酷炫的 CNodeMD

D
dislido#16·8 年前

当你试图给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)方式的速度要慢一些)

1
1160007652#17·8 年前

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

Y
yszou#18·8 年前

arr.length=0;

坑级代码。

1
1146612734#19·8 年前

回复测试

M
mrxf#20·8 年前
引用 dbit-xia@mrxf @xiaozhouge 赋值会造成变量引用就变了吧 来自 CNodeMD

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

来自酷炫的 CNodeMD

5
51ding#21·8 年前

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

H
hlj2722#22·8 年前

学习

H
hlj2722#23·8 年前

学习

参与回复
登录后即可参与回复。登录