我将以我的问题的简化示例开始。
function foo(arr) {
let limit = 1,
count = 0;
for (let i=0, len=arr.length; i<len;) {
if (arr[i] === '0' || arr[i] === '1') {
let start = i;
do {
if (i - start >= limit) {
count++;
}
i++;
} while (i < len && arr[i] === '0' || arr[i] === '1');
} else {
i++;
}
}
return count;
}
function bar(arr) {
let limit = 1,
count = 0;
for (let i=0, len=arr.length; i<len;) {
if (arr[i] === '0' || arr[i].charCodeAt(0) === 49) {
let start = i;
do {
if (i - start >= limit) {
count++;
}
i++;
} while (i < len && arr[i] === '0' || arr[i].charCodeAt(0) === 49);
} else {
i++;
}
}
return count;
}
let arr = ['0', '2', '3', '0', '1', '0', '4', '2', '0'];
console.log(bar(arr));
console.log(foo(arr));
&#13;
上述函数返回数组中模式出现的总次数,在某个连续限制之后开始计数。它们是我实际功能的简化示例,我只想在arr[i].charCodeAt(0) === 49
时评估i < len
这样的表达式。
foo函数按预期工作,但是如果我在条件中包含一个函数调用,就像在bar中一样,它首先被计算,然后抛出一个 TypeError 试图评估一个未定义的索引
我可以在另一个 i<len
检查之前在do-while-loop中移动该表达式。我想知道为什么函数优先于上面&#34;从左到右&#34;评估,如果还有别的办法可以防止它。
答案 0 :(得分:3)
它会抛出一个TypeError,试图评估一个未定义的索引。
因为arr[9]
不存在,只需输入一个控制台语句来检查相同内容。
<强>演示强>
function foo(arr) {
let limit = 1,
count = 0;
for (let i=0, len=arr.length; i<len;) {
if (arr[i] === '0' || arr[i] === '1') {
let start = i;
do {
if (i - start >= limit) {
count++;
}
i++;
} while (i < len && arr[i] === '0' || arr[i] === '1');
} else {
i++;
}
}
return count;
}
function bar(arr) {
let limit = 1,
count = 0;
for (let i=0, len=arr.length; i<len;) {
if (arr[i] === '0' || arr[i].charCodeAt(0) === 49) {
let start = i;
do {
if (i - start >= limit) {
count++;
}
i++;
console.log(i);
} while (i < len && arr[i] === '0' || arr[i].charCodeAt(0) === 49);
} else {
i++;
}
}
return count;
}
let arr = ['0', '2', '3', '0', '1', '0', '4', '2', '0'];
console.log(bar(arr));
console.log(foo(arr));
<强>解释强>
您的陈述相当于写作
var a = 1;
var b = 2;
a < 1 && b < 2 || true; //return true
a < 1 && b < 2 || false; //return false
因为您使用了||在没有()
的表达式中,除非前两个表达式为true
,否则将对其进行评估。
使用()
作为
} while (i < len && (arr[i] === '0' || arr[i].charCodeAt(0) === 49));
<强>演示强>
function foo(arr) {
let limit = 1,
count = 0;
for (let i=0, len=arr.length; i<len;) {
if (arr[i] === '0' || arr[i] === '1') {
let start = i;
do {
if (i - start >= limit) {
count++;
}
i++;
} while (i < len && arr[i] === '0' || arr[i] === '1');
} else {
i++;
}
}
return count;
}
function bar(arr) {
let limit = 1,
count = 0;
for (let i=0, len=arr.length; i<len;) {
if (arr[i] === '0' || arr[i].charCodeAt(0) === 49) {
let start = i;
do {
if (i - start >= limit) {
count++;
}
i++;
console.log(i);
} while (i < len && (arr[i] === '0' || arr[i].charCodeAt(0) === 49));
} else {
i++;
}
}
return count;
}
let arr = ['0', '2', '3', '0', '1', '0', '4', '2', '0'];
console.log(bar(arr));
console.log(foo(arr));
答案 1 :(得分:0)
你的索引用完了。但是为什么bar()会引发一个foo()没有的异常?因为javascript在索引之外返回“undefined”类型的对象。但是该对象没有方法charCodeAt()并且引发了异常。
let arr = ['a', 'b'] // note there is no arr[2]
console.log(arr[2]); // undefined
console.log(arr[2] === undefined); // true
try
{ console.log(arr[2].charCodeAt(0));
}
catch(e)
{ console.log(e.message); // Cannot read property 'charCodeAt' of undefined
}