亡羊补牢--函数

94 阅读3分钟

上次的函数还剩下一点点,这次来补全。

作用域

变量使用使用区间的, 变量不是说声明之后在哪里都可以用, 他有一个使用的范围, 我们把这个范围叫做作用域。

作用域分为两种

  1. 全局作用域

                    JS 给我们提供了一个叫做 window 的全局作用域, 可以理解为 整个 script 标签内的作用域, 就是全局作用域
                    
                    全局变量都会挂载到 window 对象上
                    
    
  2. 局部作用域
    在 JS 中, 有 且只有 函数能够创建 局部作用域(函数作用域), 局部作用域开始和结束位置, 就是函数代码段的开始和结束位置

                    在 局部作用域(函数作用域)内 声明的变量叫做局部变量
                    
                    局部变量 不会挂载到 window 对象上
       
                    以局部变量为荣, 以全局变量为耻 
    
  3. 块级作用域(这个以后说)

作用域链

在查找变量时, 会先在当前作用域内查找, 找到就用, 没找到去上层查找, 一直会查找到顶层作用域(全局---window)

然后在查找过程中, 我们把逐层向上的一层一层查找 所构成的一个链条 叫做作用域链(实际是没有作用域链的,这是一个纯概念性的东西)

变量的访问规则

变量访问会先在当前作用域内查找, 找到拿来直接用, 如果没有找到, 会去上层作用域查找, 找到直接用

如果上层作用域没找到, 会继续去上层作用域 的 上层作用域内查找, 找到直接用, 没找到会继续往上

如果找到了全局作用域内 还是没有变量, 那么就会报错 num is not defined

变量的赋值规则

变量赋值会 现在当前作用域内查找, 找到直接拿来赋值, 如果没找到, 会去上层作用域查找, 找到直接赋值

如果上层作用域也没找到, 会继续去上层作用域 的 上层作用域内查找, 找到直接赋值, 没找到继续往上

如果找到了全局作用域内, 还是没有找到变量, 那么会直接将变量定义在当前作用域内(全局作用域)然后赋值

重点: 作用域链 只会向上查找, 不会向下

eg:

         function fn() {

         function fn1() {
         
             num = 1000;
             
         }
         
         fn1()
         
     }
     
     fn()
     
     console.log(num)
    
      首先 在 fn1 这个作用域内 给变量 num 赋值
           那么 会先在当前作用域(fn1)查找 num,  但是没找到, 所以会去上层作用域内查找(fn)
           
           在 fn 作用域内查找后, 发现还是没有, 去继续去上层作用域内查找(全局---window)
           
           然后发现, 在全局作用域内 仍没有找到一个叫做 num 的变量
           那么会直接将 num 定义在全局, 然后赋值。

递归函数

在函数内部, 调用自身, 此时就是写了一递归, 但 它是死递归。

想写一个正确的递归函数, 需要在递归内部, 写上 返回点(到某个条件时, 停止递归)。 eg:

           function fn(n) {
         1. 先写折返点, 到某个条件停止递归
        if (n == 1) return 1
         2. 不符合结束递归时的代码
        return n * fn(n - 1)
    }

斐波那契数列

       有一个数列
       第一位和第二位 固定为 1
       从第三位开始, 每个位置的数字, 是前两位的和
     *  1  1  2  3  5  8  13   21   34
    function fn(n) {
        if (n == 1 || n == 2) {
            return 1
        }
        // return 数列中第 4 位 的值   +   数列中 第 3 位的值
        return fn(n - 1) + fn(n - 2)
    }
    var sum = fn(5)
    console.log(sum)