发表于: 2020-03-12 20:43:26

0 1604


今天完成的事情:


认清了函数的本质,对递归有了简单的了解


//根据输入的第几位输出斐波拉基数
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会自动在该位置利用对应的构造函数,创建对象来访问原始类型的属性



返回列表 返回列表
评论

    分享到