这是我参与8月更文挑战的第30天,活动详情查看:8月更文挑战
全局作用域和函数作用域
在ES6出来之前,js的作用域只有全局作用域和函数作用域。
我们把定义在全局作用域中的变量,成为全局变量,定义在函数里面的称之为局部变量。 他们之间有个规律:
函数里面能访问外面的变量,而函数外面不能访问函数里面的变量
举例:
var a = 1;
function fn() {
var b = 2;
console.log(a);//函数里面能访问外面的变量
innerFn();
function innerFn() {
var c = 3;
console.log(a);//函数里面能访问外面的变量
console.log(b);//函数里面能访问外面的变量
}
fn();
}
但是如果在innerFn外面访问变量c,或者fn外面访问b或c,都会报错! 这有点像生活中的单向透视玻璃,里面能看到外面,外面看不见里面。
递归
递归就是在函数体内调用本函数
一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
递归注意两点:
- 找规律
- 找出口,即边界条件,不然会导致死循环
例如:写一个方法计算n的阶层
//分析:
// n的阶层=n*(n-1)的阶层,
// (n-1)的阶层=(n-1)*(n-2)的阶层,
// .....
// 一直到
// n=1时或者n=0时得出结果(出口)
//代码如下:
function mul(n){
if(n==0||n==1){
return 1;
}
return n*mul(n-1);
}
console.log(mul(20));
若使用的是函数表达式时:
var mul = function (n){
if(n==0||n==1){
return 1;
}
return n*mul(n-1);
}
console.log(mul(20));
也可以使用arguments.callee指代本函数,但注意:在严格模式下不支持使用arguments.callee
function mul(n){
if(n==0||n==1){
return 1;
}
return n*arguments.callee(n-1);
}
递归的好处:可以让代码变得简洁,大大地减少了程序的代码量
递归的缺点:相对常用的算法如普通循环等,运行效率较低
因此,应该尽量避免使用递归,除非没有更好的算法或者某种特定情况,递归更为适合的时候。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出