发表于: 2020-03-12 20:43:26
0 1598
今天完成的事情:
认清了函数的本质,对递归有了简单的了解
//根据输入的第几位输出斐波拉基数
function f(n){
if(n===1 || n===2){
return 1;
}
return f(n-1)+f(n-2);
//假设参数为5 在执行栈中大概这样的流程,执行完从执行栈中删除调用的函数
//f(5)=f(4)+f(3) 执行f4
//f(4)=f(3)+f(2) 执行f3
//f(3)=f(2)+f(1) 执行f2 由于n=2时为1 转换为f(3)=2
//f(4)=2+1 =3
//f(5)=3+2 =5
}
console.log(f(5))
//阶层算法
function f(n){
if(n===1){
return 1;
}
return n*f(n-1);
//假设参数为5
//f(5)=5*f(4)
//f(4)=4*f(3)
//f(3)=3*f(2)
//f(2)=2*f(1)
}
console.log(f(5))
# 递归
函数直接或间接调用自身
避免无限递归,无限递归会导致执行栈溢出
对比死循环
- 死循环不会报错,也不会导致栈溢出
- 无限递归会导致栈溢出
## 执行栈
任何代码执行都必须有一个执行环境,执行环境为代码的执行提供支持
执行环境是放到执行栈中的
每个函数的调用,都需要创建一个函数的执行环境,函数调用结束,执行环境销毁
执行栈有相对固定的大小,如果执行环境太多,执行栈无法容纳,会报错
## 尾递归
如果一个函数最后一条语句是调用函数,并且调用函数不是表达式的一部分,则该语句称之为尾调用,如果尾调用是调用自身函数则称为尾递归
某些语言或执行环境会对尾调用进行优化,他们会立即销毁当前函数,避免执行栈空间被占用
在浏览器执行环境中,尾调用没有优化,但在nodejs环境中有优化
明天计划的事情:
学习JS原生标准库
遇到的问题:
递归的尾调用优化 有点复杂
收获:
# 函数的本质
函数的本质就是对象
> 所有对象都是通过关键字new出来的 ``` new 构造函数() ```
```js
var obj = {
x:y,
y:34
}
//实际创建过程
var obj = new Object();
obj.x = 2;
obj.y = 34
var arr = [1,2,3];
//实际创建过程
arr = new Array(3);
arr[0] = 1;
arr[1] = 2;
arr[3] = 3;
```
所有的函数,都是通过``` new Function() ``` 创建
```js
// function sum(a,b){
// return a+b;
// }
//其本质是
var sum = new Function("a","b","return a+b");
console.log(sum(3,5));
```
> Function
由于函数本身就是对象,因此函数中,可以拥有各种属性
## 包装类
JS为了增强原始类型的功能,为boolean,string,number分别创建了一个 构造函数:
1. Boolean
2. String
3. Number
如果语法上,将原始类型当做对象使用时(一般是在使用属性时),JS会自动在该位置利用对应的构造函数,创建对象来访问原始类型的属性
评论