Javascript - 为什么首先评估布尔表达式中的函数调用?
Javascript - Why are function calls inside boolean expressions evaluated first?
我将从我的问题的一个简化示例开始。
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));
以上函数return数组中模式出现的总次数,在某个连续限制后开始计数。它们是我的实际函数的简化示例,我只想在 i < len
.
时评估 arr[i].charCodeAt(0) === 49
这样的表达式
foo 函数按预期工作,但如果我像在 bar 中那样在我的 while 条件中包含一个函数调用,它首先被评估,并抛出一个 TypeError 尝试评估未定义的索引.
我可以在 另一个 i<len
检查之前将该表达式移动到 do-while 循环中。我想知道为什么函数优先于 "left-to-right" 评估,如果有其他我可以做的事情来防止它。
it throws a TypeError trying to evaluate an undefined index.
因为 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));
您 运行 已超出索引。但是为什么 bar() 会引发异常而 foo() 不会呢?因为 javascript returns "undefined" 类型的对象在 out-of-index 上。但是该对象没有方法 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
}
我将从我的问题的一个简化示例开始。
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));
以上函数return数组中模式出现的总次数,在某个连续限制后开始计数。它们是我的实际函数的简化示例,我只想在 i < len
.
arr[i].charCodeAt(0) === 49
这样的表达式
foo 函数按预期工作,但如果我像在 bar 中那样在我的 while 条件中包含一个函数调用,它首先被评估,并抛出一个 TypeError 尝试评估未定义的索引.
我可以在 另一个 i<len
检查之前将该表达式移动到 do-while 循环中。我想知道为什么函数优先于 "left-to-right" 评估,如果有其他我可以做的事情来防止它。
it throws a TypeError trying to evaluate an undefined index.
因为 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));
您 运行 已超出索引。但是为什么 bar() 会引发异常而 foo() 不会呢?因为 javascript returns "undefined" 类型的对象在 out-of-index 上。但是该对象没有方法 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
}