06-JavaScript函数

JavaScript函数

  • 函数是专门用于封装代码的,函数是一段可以随时被反复执行的代码块

  • 函数格式

    function 函数名称(形参列表){
        被封装的代码;
    }
    
  • 使用函数的好处

    • 冗余代码变少了
    • 需求变更,需要修改的代码变少了
  • 函数的注意点

    • 一个函数可以有形参也可以没有形参(零个或多个)
    • 一个函数可以有返回值也可以没有返回值
    • 函数没有通过return明确返回值,默认返回undefined
    • return的作用和break相似,所以return后面不能编写任何语句(永远执行不到)
      • break作用是立即结束switch语句或者循环语句
      • return作用立即结束当前所在函数
    • 调用函数时实参的个数和形参的个数可以不相同
    • JavaScript中的函数和数组一样,都是引用数据类型(对象类型)
    • 其他编程语言中函数是不可以嵌套定义的,但是在JavaScript中函数可以嵌套定义

函数定义步骤

  1. 书写函数的固定格式
  2. 给函数起一个有意义的名称
    • 提升代码的阅读性
    • 函数名称也是标识符的一种,所以也需要遵守标识符的命名规则和规范
  3. 确定函数的形参列表
  4. 将需要封装的代码拷贝到{}中
  5. 确定函数的返回值
    • 可以通过return 数据;的格式将函数中计算的结果返回给函数的调用者

函数arguments

  • 因为console.log();也是通过()来调用的,所以log也是一个函数
  • log函数的特点:可以接收1个或多个参数
  • log函数可以接收1个或多个参数内部的实现原理就用到了arguments
  • arguments的作用:保存所有传递给函数的实参
  • 每个函数都用一个叫arguments的东西
  • arguments其实是一个伪数组

函数扩展运算符

  • 扩展运算符在等号左边,将剩余的数据打包到一个新的数组中只能写在最后
  • 扩展运算符在等号右边,将数组中的数据解开
  • 扩展运算符在函数的形参列表中,将传递给函数的所有实参打包到一个数组中

函数形参默认值

  • 在ES6之前可以通过逻辑运算符来给形参指定默认值
  • 格式:条件A || 条件B
  • 如果条件A成立,那么就会返回条件A,如果条件A不成立,无论条件B是否成立,都会返回条件B
  • 从ES6开始,可以直接在形参后面通过=指定默认值
  • ES6开始的默认值还可以从其他的函数中获取

匿名函数

  • 匿名函数就是没有名称的函数
  • 匿名函数不能够只定义不使用
  • 匿名函数的应用场景
    • 作为其他函数的参数
    • 作为其他函数的返回值
    • 作为一个立即执行的函数如果想让匿名函数立即执行,那么必须使用()将函数的定义包裹起来

箭头函数ES6

  • 箭头函数是ES6中新增的一种定义函数的格式

  • 目的就是为了简化定义函数的代码

  • ES6之前定义函数的格式

    function 函数名称(形参列表){
        需要封装的代码;
    }
    let 函数名称 = function(形参列表){
        需要封装的代码;
    }
    
  • 从ES6开始定义函数的格式

    let 函数名称 = (形参列表) =>{
        需要封装的代码;
    }
    
  • 箭头函数的注意点

    • 在箭头函数中如果只有一个参数,那么()可以省略
    • 在箭头函数中如果{}中只有一句代码,那么{}也可以省略

函数中变量作用域

  • 在JavaScript中{}外面的作用域,我们称之为全局作用域
  • 在JavaScript中函数后面的{}中的作用域,我们称之为"局部作用域"
  • 在ES6中只要{}没有和函数结合在一起,那么应该称为"块级作用域"
  • 块级作用域和局部作用域的区别
    • 在块级作用域中通过var定义的变量是全局变量
    • 在局部作用域中通过var定义的变量是局部变量
  • 无论是在块级作用域还是局部作用域,省略变量前面的let或者var就会变成一个全局变量

作用域链

ES6之前

  • ES6之前定义变量通过var
  • ES6之前没有块级作用域,都是全局作用域和局部作用域
  • ES6之前函数大括号外的都是全局作用域
  • ES6之前函数大括号中的都是局部作用域
  • ES6之前作用域链
    • 全局作用域我们又称之为0级作用域
    • 定义函数开启的作用域就是1级/2级/3级...作用域
    • JavaScript会将这些作用域链接在一起形成一个链条,这个链条就是作用域链
    • 除0级作用域以外,当前作用域级别等于上一级+1
  • 变量在作用域链查找规则
    • 现在当前找,找到就使用当前作用域找到的
    • 如果当前作用域中没有找到,就去上一级作用域中查找
    • 依次类推直到0级为止,如果0级作用域还没找到,就报错

ES6之后

  • ES6定义变量通过let
  • ES6除了全局作用域,局部作用域以外,还新增了块级作用域
  • ES6虽然新增了块级作用域,但是通过let定义变量并无差异(都是局部变量)
  • ES6作用域链和ES6之前差别不大,ES6之前是定义函数就会开启作用域,ES6除了定义函数会开启作用域,代码块也会开启作用域

预解析

  • 浏览器在执行JS代码的时候会分成两部分操作:预解析以及逐行执行代码,也就是说浏览器不会直接执行代码, 而是加工处理之后再执行,这个加工处理的过程, 我们就称之为预解析

  • 预解析规则

    • 将变量声明和函数声明提升到当前作用域最前面
    • 将剩余代码按照书写顺序依次放到后面
    • 通过let定义的变量不会被提升(不会被预解析)
    function say() {
        console.log('hello world');
    }
    ES6之前的这种定义函数的格式,是会被预解析的,所以可以提前调用
    
    var say = function() {
        console.log('hello world');
    }
    如果将函数赋值给一个var定义的变量,那么函数不会被预解析,只有变量会被预解析
    

你可能感兴趣的:(06-JavaScript函数)