都2022年了 你还不知道的有关函数的那些重要知识点

51 阅读5分钟

1、什么是函数 函数 可以理解为一个盒子

2、写一个函数(或者说一个完整的函数)

  • 分为两部分
    1. 定义阶段
    1. 调用阶段

3、函数的定义

语法: function () {}

两种定义函数的方式

  1. 赋值式定义 var fn = function () {}

  2. 声明式定义 function 函数名() {}

eg:: 赋值式定义

var fn = function () {}

console.log(fn)

eg: // 声明式定义

function fn1() {}

console.log(fn1)

3、函数的调用

不管函数定义是如何定义的, 调用方式永远只有一种

语法: 函数名()

4、函数声明式和赋值式的区别

  1. 书写不同
  2. 打印时声明式会带上函数名, 赋值式没有
  3. 调用时有差异声明式: 可以在函数定义前调用

5、函数的参数

参数分为两个

形参 函数名后(function) 后边的小括号内部, 每书写一个 就相当于在函数内部声明一个变量, 可以在函数内部去调用

实参 调用函数时的小括号内部书写的值, 就是实参, 实参与形参为 一一对应的关系

形参与实参会一一对应

  • 如果实参数量 少于 形参 那么前边的形参对应接受值, 没有对应实参 的 形参 值 为 undefined

  • 如果形参数量 少于 实参 那么会一一对应后, 多余的实参无法通过 参数获取

6、函数的返回值

语法: return 需要返回的内容

函数默认返回值

  • 我们可以不写 return 函数 会默认在代码段最后一行 写上 retrun undefined

return功能

  • 具有中断函数执行的功能

  • 如果不想中断函数, 那么一定要将 return 放在函数的最后

  • 除非就是想要通过 return 中断函数的运行

return 中断函数
<script>
​
•        function fn() {
​
•            console.log(1)
​
•            return
​
•            console.log(2)
​
•            console.log(3)
​
•            console.log(4)
​
•            console.log(5)
​
•        }
​
•        fn()
</script>

7、函数的预解析

  • 函数的预解析, 可以能会遇上同名变量的变量提升(变量的预解析) 直接以函数为主
​
 * 书写代码
 * 
 *  fn()    
     function fn() {
         console.log(1)
      }
      fn()  
            
预解析之后(会把函数提升到当前作用域最顶层) (暂时理解为 当前代码最开始的第一行)
​
 1. fn()    不需要
 2. function fn() {}    需要预解析
 3. fn()    不需要
 
 1. function fn() {}    // 提升到了当前代码最开始的第一行
 2. fn() // 正常调用
 3. fn() // 正常调用
 
 * 
 *  var fn = 'hhh'
    console.log(fn)
​
      fn()   
           function fn() {
           console.log(1)
           }
      fn()   
         在 JS 中 只有变量和函数才会有预解析或者 提升
            1. var fn = 'hhh'       // 有提升
            2. console.log(fn)      // 没有
​
            3. fn()                 // 没有
            4. function fn() {      // 有提升
                 console.log(1)
                }
            5. fn()                 // 没有
​
预解析之后
 1. function fn() {
           console.log(1)
 }
 2. var fn;  // 没意义3. fn = 'hhh'   // 这行很重要, 直接将变量内保存的 函数 更改为了 'hhh'4. console.log(fn)  // 按照分析, 此处应该打印 'hhh'5. fn()     // 按照分析, 此处 fn 的值应该 'hhh' 所以会报错 fn is not a function6. fn()     // 按照分析, 此处 fn 的还是 'hhh' ,所以还会报错 fn is not a function
​
​
8、函数的作用域

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

2、作用域分为两种

1、全局作用域

JS 给我们提供了一个叫做 window 的全局作用域, 可以理解为 整个 script 标签内的作用域, 就是全局作用域

全局变量都会挂载到 window 对象上

2、局部作用域

在 JS 中, 有 且只有 函数能够创建 局部作用域(函数作用域), 局部作用域开始和结束位置, 就是函数代码段的开始和结束位置

在局部作用域(函数作用域)内 声明的变量叫做局部变量

局部变量 不会挂载到 window 对象上

使用感受: 以局部变量为荣, 以全局变量为耻

9、作用域链

1、什么是作用域链

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

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

2、变量的访问规则

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

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

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

3、变量的赋值规则

变量赋值会 现在当前作用域内查找, 找到直接拿来赋值, 如果没找到, 会去上层作用域查找, 找到直接赋值 如果上层作用域也没找到, 会继续去上层作用域 的 上层作用域内查找, 找到直接赋值, 没找到继续往上 如果找到了全局作用域内, 还是没有找到变量, 那么会直接将变量定义在当前作用域内(全局作用域)然后赋值

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

10、递归函数

在函数内部, 调用自身, 此时就是写了一递归, 但 它是死递归。要想写一个正确的递归函数, 需要在递归内部, 写上 返回点(到某个条件时, 停止递归)

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

以上均是个人学习理解js的一些个人感受,望各位大佬不吝指教,谢谢!