在Javascript中使用这种循环是否安全?
denseArray = [1,2,3,4,5, '...', 99999]
var x, i = 0
while (x = denseArray[i++]) {
document.write(x + '<br>')
console.log(x)
}
document.write('Used sentinel: ' + denseArray[i])
document.write('Size of array: ' + i)
使用内置的哨兵,它比for循环要短,并且对于大型阵列也可能更有效。 sentinel 将呼叫者标记为发生了不寻常的事情。
该数组必须是dense array才能起作用!这意味着没有其他 undefined
值,除了数组中最后一个元素之后的值。我几乎从不使用稀疏数组,而仅使用密集数组,所以对我来说没关系。
要记住的另一个更重要的要点(感谢@Jack Bashford提醒)是,这不仅是未定义为哨兵。如果数组值为0,false或其他任何伪造的值,则循环将停止。因此,您必须确保数组中的数据没有0
,""
,''
,``,null
,{ {1}}和undefined
。
这里是否存在“超出范围”的问题,或者我们可以将Javascript中的数组视为“无限”(如果内存不满)? 未定义意味着浏览器可以将其设置为任何值,因为它是未定义的,还是我们可以认为条件测试始终有效? Javascript中的数组很奇怪,因为“它们是对象”,所以最好问一下。
我无法使用以下标签在Stackoverflow上找到答案:NaN
。 结果为零!
我已经考虑了一段时间,并用了足够多的时间开始担心。但我要使用它,因为它美观大方,易于查看,简短,在大数据中可能有效。 [javascript] [sentinel] [while-loop] [arrays]
是数组的大小很有用。
更新
i
优化且已为开发人员使用的denseArray.forEach((x)=>{...code})
。无需遇到虚假的价值观。它有MDN confirms。 答案 0 :(得分:1)
即使以后您的代码不会被其他人查看,最好还是使其更具可读性和组织性。条件测试中的值分配(递增和递减运算符除外)通常不是一个好主意。
您的检查也需要更加具体,因为[0, '']
都为假。
denseArray = [1,2,3,4,5, '...', 99999]
for(let i = 0; i < denseArray.length; i++) {
let x = denseArray[i]
document.write(x + '<br>');
console.log(x);
if (/* check bad value */) break;
}
document.write('Used sentinel: ' + denseArray[i])
document.write('Size of array: ' + i)
根据我的经验,如果以可读性甚至可靠性为代价,那么节省几行代码通常是不值得的。
编辑:这是我用来测试速度的代码
const arr = [];
let i;
for (i = 0; i < 30000000; i++) arr.push(i.toString());
let x;
let start = new Date();
for(i = 0; i < arr.length; i++) {
x = arr[i];
if (typeof x !== 'string') break;
}
console.log('A');
console.log(new Date().getTime() - start.getTime());
start = new Date();
i = 0;
while (x = arr[i++]) {
}
console.log('B');
console.log(new Date().getTime() -start.getTime());
start = new Date();
for(i = 0; i < arr.length; i++) {
x = arr[i];
if (typeof x !== 'string') break;
}
console.log('A');
console.log(new Date().getTime() - start.getTime());
start = new Date();
i = 0;
while (x = arr[i++]) {
}
console.log('B');
console.log(new Date().getTime() -start.getTime());
start = new Date();
for(i = 0; i < arr.length; i++) {
x = arr[i];
if (typeof x !== 'string') break;
}
console.log('A');
console.log(new Date().getTime() - start.getTime());
start = new Date();
i = 0;
while (x = arr[i++]) {
}
console.log('B');
console.log(new Date().getTime() -start.getTime());
for循环甚至还有一个额外的if语句来检查错误的值,并且仍然更快。
答案 1 :(得分:0)
搜索ScrollView
会得到结果:
意见从it looks like a common error where you try to compare values到If there is quirkiness in all of this, it's the for statement's wholesale divergence from the language's normal syntax不等。 javascript assignment in while
是添加冗余的语法糖。它尚未与for
一起过时while
。
首先要考虑的问题是它是否安全。 MDN在数组中说:Using an invalid index number returns undefined,所以使用起来很安全。在有条件的情况下对作业进行测试是安全的。可以同时完成多个分配,但是带有if-goto
,var
或let
的声明不会像assign do那样返回,因此该声明必须在条件之外。敬请发表评论,以日后向其他人或您自己解释,数组必须保持密集且没有虚假的值,否则它可能会出错。
要允许const
,false
或0
(除""
以外的任何虚假名称),然后将其扩展为:undefined
,但它并不比普通数组长度比较。
有用吗? Yes:
while ((x = denseArray[i++]) !== undefined) ...
否则必须写
while( var = GetNext() )
{
...do something with var
}
通常,最好使用开发人员熟知的var = GetNext();
while( var )
{
...do something
var = GetNext();
}
。无需考虑虚假的价值观。它有good browser support。 但是,它很慢!
I made a jsperf显示 forEach比白名单慢了60%!测试还显示,在我的计算机上denseArray.forEach((x) => { ... })
比for
快一点!另请参阅@Albert答案以及测试结果,显示 for的速度比while稍快。
使用while
是安全的,它可能并非没有错误。在编码时,您可能知道您的数据,但是您不知道是否有人复制粘贴该代码以用于其他数据。