雄辩的Javascript,第7章-尝试抓球
我知道它试图在函数中模拟break语句,我对“try-catch”有一个基本的理解,但我不能理解这个过程 这是你的电话号码 我也不明白代码下面的行- 如果操作函数抛出Break,forEach将吸收异常 停止循环 这是实际的代码-雄辩的Javascript,第7章-尝试抓球,javascript,Javascript,我知道它试图在函数中模拟break语句,我对“try-catch”有一个基本的理解,但我不能理解这个过程 这是你的电话号码 我也不明白代码下面的行- 如果操作函数抛出Break,forEach将吸收异常 停止循环 这是实际的代码- var Break = {toString: function() {return "Break";}}; function forEach(array, action) { try { for (var i = 0; i < array.leng
var Break = {toString: function() {return "Break";}};
function forEach(array, action) {
try {
for (var i = 0; i < array.length; i++)
action(array[i]);
}
catch (exception) {
if (exception != Break)
throw exception;
}
}
var Break={toString:function(){返回“Break”;};
函数forEach(数组、操作){
试一试{
对于(var i=0;i
序言:forEach不是ES5中的版本(我相信这本书早于ES5)。ES5的Array#forEach
没有提供任何提前中断循环的方法(也就是说,没有代码调用Array#forEach
看到异常);相反,如果需要提前停止,可以使用Array#some
或Array#every
。这张便条只是为了防止人们感到困惑。下面是关于OP问题中的forEach
,而不是ES5
在JavaScript中,您可以抛出任何值—一个错误
对象、任何其他对象、一个数字、一个字符串,等等
他们在那里做的是定义一个特定的对象,Break
,他们让你用它作为一个例外,告诉forEach
函数停止在数组中循环
如果迭代函数抛出特定对象Break
对象,则forEach
将停止循环,但不会抛出异常。因此,下面的代码不会抛出,而是停在2
:
forEach([1, 2, 3, 4], function(entry) {
console.log(entry);
if (entry === 2) {
throw Break;
}
});
输出:
1
2
1
TypeError: undefined is not a function
1
2
输出:
1
2
1
TypeError: undefined is not a function
1
2
这样做的目的是检查抛出的是否是Break
对象(尽管这不是一个很好的检查),如果不是,它将重新抛出异常,以便显示给调用forEach
的代码。但是如果它是Break
对象,那么它只是默默地停止循环
(这不是一个很好的检查的原因是,如果异常是一个字符串或数字——在JavaScript中,它们可能是——它将做不必要的工作,执行类型强制以尝试查看它是否可以使参数匹配。它实际上应该是if(exception!==Break)
。)
Tangent(但这可能有助于进一步说明发生了什么):从性能角度来看,这种forEach
变体的设计并不理想。设置一个try/catch
块很便宜,但它不是免费的,而抛出一个异常是非常昂贵的。另一种方法是使用迭代器函数的返回值,如下所示:
var Break = {toString: function() {return "Break";}};
function forEach(array, action) {
for (var i = 0; i < array.length; i++) {
if (action(array[i]) === Break) {
return;
}
}
}
输出:
1
2
1
TypeError: undefined is not a function
1
2
1.
2.
当然,这需要在每次迭代中对迭代器的返回值进行比较。这样做的成本与设置try/catch
块非常相似,但在大多数引擎上更便宜
但是,现代发动机真的有速度差吗
对。在我们不打破循环的情况下存在差异,在我们打破循环的情况下存在巨大差异:
在这种情况下,我们不中断循环(我们不抛出
或返回中断
对象,因此循环完成):
差别相当小,除了Firefox的SpiderMonkey之外,所有引擎都给了返回
(比较)版本以优势。但是,不管他们走哪条路,成本都是相似的
但以下是我们打破循环的版本:
正如您所看到的,显著地最好是返回Break代码>比到<代码>抛出断点代码>