Mic*_*ker 470 javascript arrays jslint
我在JavaScript中使用数组(包括w3schools和devguru)阅读的大多数教程都建议您可以使用var test = new Array(4);语法将整数传递给Array构造函数来初始化具有一定长度的数组.
在我的js文件中大量使用这种语法之后,我通过jsLint运行了一个文件,它吓坏了:
错误:第1行字符22处的问题:预期')'而是看到'4'.
var test = new Array(4);
第1行第23个问题:预期';' 而是看到')'.
var test = new Array(4);
第1行字符23处的问题:预期标识符而不是')'.
通过阅读jsLint对其行为的解释后,看起来jsLint并不真正喜欢new Array()语法,而是[]在声明数组时更喜欢.
所以我有几个问题.首先,为什么?我是否因使用new Array()语法而冒任何风险?是否存在我应该注意的浏览器不兼容性?第二,如果我切换到方括号语法,有没有办法声明一个数组并将其长度全部设置在一行,或者我必须做这样的事情:
var test = [];
test.length = 4;
Run Code Online (Sandbox Code Playgroud)
Rub*_*olk 495
Array(5) 给你一个长度为5但没有值的数组,因此你不能迭代它.
Array.apply(null, Array(5)).map(function () {}) 给你一个长度为5且未定义为值的数组,现在它可以迭代.
Array.apply(null, Array(5)).map(function (x, i) { return i; }) 为您提供长度为5且值为0,1,2,3,4的数组.
Array(5).forEach(alert)什么都不做,Array.apply(null, Array(5)).forEach(alert)给你5个警报
ES6给我们Array.from所以现在你也可以使用Array.from(Array(5)).forEach(alert)
如果你想用一定的值进行初始化,这些都是很好的知道......
Array.from('abcde'),Array.from('x'.repeat(5))
或者Array.from({length: 5}, (v, i) => i) // gives [0, 1, 2, 3, 4]
Fel*_*ing 367
为什么要初始化长度?从理论上讲,没有必要这样做.它甚至可能导致令人困惑的行为,因为所有使用它length来查明数组是否为空的测试都会报告该数组不为空.
一些 测试表明,如果之后填充数组,设置大型数组的初始长度可以更有效,但性能增益(如果有的话)似乎因浏览器而异.
jsLint不喜欢new Array()因为构造函数不明确.
new Array(4);
Run Code Online (Sandbox Code Playgroud)
创建一个长度为 4 的空数组.但是
new Array('4');
Run Code Online (Sandbox Code Playgroud)
创建一个包含该值 的数组'4'.
关于你的评论:在JS中,你不需要初始化数组的长度.它动态增长.您可以将长度存储在某个变量中,例如
var data = [];
var length = 5; // user defined length
for(var i = 0; i < length; i++) {
data.push(createSomeObject());
}
Run Code Online (Sandbox Code Playgroud)
AP.*_*AP. 226
使用ES2015,.fill()您现在可以简单地执行:
// `n` is the size you want to initialize your array
// `0` is what the array will be filled with (can be any other value)
Array(n).fill(0)
Run Code Online (Sandbox Code Playgroud)
这比简洁得多 Array.apply(0, new Array(n)).map(i => value)
可以0放入in .fill()并运行不带参数,这将填充数组undefined.(但是,这将在Typescript中失败)
Vla*_*lad 69
[...Array(6)].map(x=>0);
// [0, 0, 0, 0, 0, 0]
Run Code Online (Sandbox Code Playgroud)
要么
Array(6).fill(0);
// [0, 0, 0, 0, 0, 0]
Run Code Online (Sandbox Code Playgroud)
要么
Array(6).fill(null).map( (x,i) => i );
// [0, 1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)
(打字稿安全)
在创建2D数组时,Array(4).forEach( (_,i) => {} )应直观地创建新实例.但实际发生的事情是将相同的数组存储为参考.
var a = Array(3).fill([6]);
// [[6], [6], [6]]
a[ 0 ].push( 9 );
// [[6,9], [6,9], [6,9]]
Run Code Online (Sandbox Code Playgroud)
解
var a = [...Array(3)].map(x=>[]);
a[ 0 ].push( 4, 2 );
// [[4,2], [ ], [ ]]
Run Code Online (Sandbox Code Playgroud)
所以3x2阵列看起来像这样:
[...Array(3)].map(x=>Array(2).fill(0));
// [ [0,0] ,
// [0,0] ,
// [0,0] ]
Run Code Online (Sandbox Code Playgroud)
Mic*_*iti 63
最短的:
[...Array(1000)]
Run Code Online (Sandbox Code Playgroud)
Ale*_*tau 35
ES6介绍了Array.from它允许您Array从任何"类似数组"或可迭代对象创建:
Array.from({length: 10}, (x, i) => i);
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)
在这种情况下,{length: 10}表示"类数组"对象的最小定义:仅length定义属性的空对象.
Array.from 允许第二个参数映射结果数组.
Has*_*war 26
最简单的形式是使用
Array.from({ length: 3 });
// gives you
[undefined, undefined, undefined]
Run Code Online (Sandbox Code Playgroud)
与此不同的是Array(3),它会给你一个无法迭代的数组。Array.from({ length })给你一个可以轻松迭代的数组。
Array.from({ length: 3 }).map((e, idx) => `hi ${idx}`);
// ['hi 1', 'hi 2', 'hi 3']
Run Code Online (Sandbox Code Playgroud)
Šim*_*das 25
这会将length属性初始化为4:
var x = [,,,,];
Run Code Online (Sandbox Code Playgroud)
chr*_*ang 15
我很惊讶没有建议的功能解决方案允许您在一行中设置长度.以下是基于UnderscoreJS:
var test = _.map(_.range(4), function () { return undefined; });
console.log(test.length);
Run Code Online (Sandbox Code Playgroud)
由于上面提到的原因,除非我想将数组初始化为特定值,否则我将避免这样做.值得注意的是,还有其他库可以实现范围,包括Lo-dash和Lazy,它们可能具有不同的性能特征.
(作为评论,这可能更好,但是太长了)
因此,在阅读本文之后,我很好奇预分配实际上是否更快,因为理论上它应该是.但是,这篇博客提供了一些建议,提供反对意见http://www.html5rocks.com/en/tutorials/speed/v8/.
所以仍然不确定,我把它做了测试.事实证明它似乎实际上更慢.
var time = Date.now();
var temp = [];
for(var i=0;i<100000;i++){
temp[i]=i;
}
console.log(Date.now()-time);
var time = Date.now();
var temp2 = new Array(100000);
for(var i=0;i<100000;i++){
temp2[i] = i;
}
console.log(Date.now()-time);
Run Code Online (Sandbox Code Playgroud)
经过几次临时运行后,此代码产生以下结果:
$ node main.js
9
16
$ node main.js
8
14
$ node main.js
7
20
$ node main.js
9
14
$ node main.js
9
19
Run Code Online (Sandbox Code Playgroud)
var arr=[];
arr[5]=0;
alert("length="+arr.length); // gives 6
Run Code Online (Sandbox Code Playgroud)
请人们不要放弃你的旧习惯.分配内存一次然后使用该数组中的条目(从旧)开始,并在数组增长时分配多次(这不可避免地是系统在其他建议的方法下做的事情)之间的速度差异很大.
当然,除非你想用更大的数组做一些很酷的事情,否则这一切都不重要.然后呢.
看来目前在JS中似乎没有选项来设置阵列的初始容量,我使用以下内容......
var newArrayWithSize = function(size) {
this.standard = this.standard||[];
for (var add = size-this.standard.length; add>0; add--) {
this.standard.push(undefined);// or whatever
}
return this.standard.slice(0,size);
}
Run Code Online (Sandbox Code Playgroud)
需要权衡:
standard阵列并永久保留尽可能多的空间,你问了最大的数组.但如果它符合你正在做的事情那么可能会有回报.非正式时机提出
for (var n=10000;n>0;n--) {var b = newArrayWithSize(10000);b[0]=0;}
Run Code Online (Sandbox Code Playgroud)
以相当快的速度(10000左右,大约50毫秒,n = 1000000大约需要5秒),和
for (var n=10000;n>0;n--) {
var b = [];for (var add=10000;add>0;add--) {
b.push(undefined);
}
}
Run Code Online (Sandbox Code Playgroud)
超过一分钟(同一镀铬控制台上的10000秒约为90秒,或慢约2000倍).这不仅仅是分配,而且还有10000次推送,for循环等.
这是另一种解决方案
var arr = Array.apply( null, { length: 4 } );
arr; // [undefined, undefined, undefined, undefined] (in Chrome)
arr.length; // 4
Run Code Online (Sandbox Code Playgroud)
第一个参数apply()是一个这个对象绑定,我们在这里并不关心,所以我们将它设置为null.
Array.apply(..)正在调用该Array(..)函数并将{ length: 3 }对象值展开为其参数.
在现代 JS 引擎中,完全支持稀疏数组。您可以使用[]或new Array(len)以任何您喜欢的方式,即使是随机访问。字典模式似乎已成为过去。
在当前的 Chrome(我猜是任何 V8 环境)中,数组的长度可以达到 2^32-1,并且分配是稀疏的(意味着空块不会占用任何内存):
如上所述,使用new Array(size)有点危险。不要直接使用它,而是将它放在“数组创建者函数”中。您可以轻松确保此函数没有错误,并避免new Array(size)直接调用的危险。此外,您可以给它一个可选的默认初始值。这个createArray函数正是这样做的:
function createArray(size, defaultVal) {
const arr = new Array(size);
if (defaultVal !== undefined) {
// optional default value
for (let i = 0; i < size; ++i) {
arr[i] = defaultVal;
}
}
return arr;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
595733 次 |
| 最近记录: |