JavaScript中使用递归模式

JavaScript中使用递归模式


复杂算法通常比较容易使用递归实现。很多传统算法正是通过递归实现的,如阶乘函数。

function factorial(n) {
	if(n == 0) {
 		return 1
 	} else {
 		return n * factorial(n - 1)
 	}
}

递归函数的问题:错误定义或缺少终结条件会导致函数长时间运行,使浏览器出现假死现象。此外,递归函数还会受到浏览器调用栈大小的限制。

JavaScript引擎所支持的递归数量与JavaScript调用栈大小直接相关。只有IE例外,因为它的调用栈与可用系统内存相关,而其他浏览器有固定的调用栈限制。当使用了太多的递归,超过最大调用栈尺寸时,浏览器会弹出错误信息。

调用栈溢出错误可以用trycatch语句捕获。异常类型因浏览器而不同:在Firefox中,它是一个InternalError错误:在Safari和Chrome中,它是一个RangeError错误:在IE中会抛出一个一般性的Error类型:在Opera中不抛出错误,但会终止JavaSeript引擎。正确处理这些错误的方法下:

try {
 	recurse()
} catch(e) {
 	alert('errorInfo')
}

当出现调用栈尺寸限制的问题时,第一步应该定位在代码中的递归实例上。为此,有两个递归式可供选择。

第一种是直接递归模式,即一个函数调用自身。当发生错误时,这种模式比较容易 位。其一般模式如下:

function recurse() {
 	recurse()
}
recurse()

第二种是精巧模式,它包含两个函数:

function firgt() {
 	second()
}
function second() {
 	first()
}
first()

在这种递归模式中,两个函数互相调用对方,形成一个无限循环。大多数调用栈错误与这两种模式有关。常见的栈溢出原因是一个不正确的终止条件。

因此定位模式错误的第一步验证终止条件。如果终止条件是正确的,那么算法包含了太多层递归,为了能够安全地在刘览器中运行,应改用选代、制表或混合模式。

选代、制表将在后续文章中继续介绍

你可能感兴趣的:(JavaScript学习笔记,javascript,typescript)