函数
递归
所谓递归其实就是函数直接或间接调用自己
示例(用递归计算斐波那契数列):
function fibonacci(n) {
if (n == 1 || n == 2) {
return 1
};
return fibonacci(n - 2) + fibonacci(n - 1);
}
fibonacci(30)
个人观点:递归会让代码看上去更加的简洁但是递归需要系统堆栈,所以空间消耗要比非递归代码要大很多,而且如果递归的深度很大系统可能会崩溃!!
无限递归
<script>
function f(n){
return f(n-1)+f(n-2);
}
console.log(f(5));
</script>
执行栈
任何代码的执行必须都有一个执行环境
执行环境是放到执行栈
每一个函数的调用,都需要创建一个函数的执行环境,函数调用后,执行环境销毁。
无限递归执行栈溢出
对比死循环
1.死循环不会报错
2.无限递归会报错 执行栈溢出
原型
1.所有的对象 都是通过 ```new 函数```创建的
2.所有的函数也是对象
函数也是可以有属性
原型 prototype
所有的函数 都有一个属性 prototype 称为函数原型
在默认情况下 prototype 是一个普通的Object对象
在默认情况下 prototype 有一个属性 constructor 也是一对象 指向的是构造函数本身。
打印出Array的原型
let arr=new Array();
console.log(Array.prototype);
隐式原型 proto
所有的对象 都有一个属性 proto 隐式原型
在默认情况下_proto_指向的创建该对象的函数的原型
当访问一个对象时:
1.该对象自身是否拥有成员属性如果有直接使用
2.看隐式原型中是否拥有该成员属性如果有直接使用。
2.看隐式原型中是否拥有该成员属性如果有直接使用。
打印出arr的隐式原型
let arr=new Array();
console.log(arr.__proto__);
可以看出arr的隐式原型是指向Array的原型的。