JavaScript | 理解函数这一篇就够了

148 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情

前言

函数是JavaScript最重要的部分之一,每个人都知道但不一定都了解的很详细,所以今天就详解一下函数。

函数的基本介绍

对函数做一个简单的基本介绍

什么是函数

函数是命名指定完成的代码块,本质是一种数据,属于对象类型函数也是值与其他变量类型的值不同的是,函数中包含的是代码。它是可以执行的。

函数作用

  • 解决代码冗余问题,形成代码复用
  • 封装代码,让函数内部的代码不可见
  • 可以将整个项目,通过函数进行模块化

函数的种类

  • 系统函数,系统已经提供的。如 string()parseInt()
  • 自定义函数:自己命名封装函数

函数的声明方式

  • 利用函数关键字:function自定义的声明:function fn(){...}
  • 函数表达式的声明方式(函数表达式方式声明的函数只能在创建之后才能调用 执行到这个表达式才行) :var fn = function(){...}
  • 函数的构造器声明:new Function()这种方式只不过用来证明它是对象是引用类型(不建议使用)

函数的调用

  • 默认调用 fn()
  • 上下文对象调用 obj.fn(); div.onclick = function(){}
  • 实例化调用: new fn()
  • call/apply调用:fn.call()

函数的参数

函数的参数分为形参和实参,形参为函数定义时候的参数:function fn('形参'){},实参则为函数调用时的参数:fn('实参')

关于函数参数需要注意的几个点

  • 形参和实参传值是一一对应的
  • 函数的形参实际上就相当于在函数内部定义了一个变量
  • 函数也是数据,是对象。函数中有一个length属性用来表示该函数应该有多少个形参
  • ES中的函数形参、实参的个数可以不相等
    • 如果实参比形参少,这个时候多出来的形参将自动被赋予undefined
    • 如果实参比形参多,那么多出来的实参可以使用arguments对象来获得

arguments对象

当不确定有多少个参数传递的时候,可以用 arguments 来获取

arguments具体介绍

  • arguments对象只在函数内部有
  • arguments对象实际上是一个类数组的对象。
  • 类数组(伪数组)介绍:
    • 有下标、有length属性,按索引方式储存数据
    • 不具有数组的 push , pop 等方法
  • 函数中的形参在JS中可以不写,要获得传递进来的实参都可以用arguments对象获得。定义形参的原因是因为它比arguments对象使用起来方便
  • arguments对象的length属性用来确定传递进来多少个实参

arguments代码示例

    function fn(){
    //即使不定义形参也会有arguments
    console.log(arguments) //会返回传进来的实参还有length:{[3,5,length:2]}
    var sum = 0;
    for(var index in arguments){
        sum+=arguments[index]
    }
    console.log(sum)
}

fn(3,5) // 8

函数的返回值

  • return语句表示的是整个函数运行之后的结果
  • 什么时候用return什么时候不用return完全取决于你的函数的功能
  • return返回的值将返回到函数调用处

关于函数返回需要注意的几个点

- 函数在定义时如果没有使用return确定返回值那么默认返回undefined
- 函数会在执行完return语句之后立即停止执行并且退出(return语句之后的任何代码都不会执行)

如:

  function test(){
      console.log(1);
      return 2;
      console.log('返回后的值');
  }
  
  console.log(test());//1,2  不会执行return后面的代码
  //return语句后面不带有任何的返回值,函数在停止执行后将返回undefined

return的作用

  • 返回函数中要返回的值
  • 终止函数的执行(return后面如果没有内容,只是单纯的终止函数执行

关于函数的拓展

除了简单定义的基本函数,还包括其它类的(箭头函数就不说了)

回调函数

回调函数其实就是函数是你自己定义的,但是你没有去主动调用它,但是函数依然执行了

  • 比如
        [1, 2].forEach(function () {})

        div.onclick = function () {}

        setTimeout(function () {

        }, 1000)

IIFE 立即执行函数表达式(匿名函数自调用)

声明一个函数,马上调用,隐藏内部的实现,构成局部作用域 不会污染全局变量,模块化开发。

通过一个简单例子来看一下

  for (var i = 0; i < 3; i++) {
            (function (i) {
                setTimeout(function () {
                    console.log(i); //0,1,2
                })
            })(i);
        }

        for (var i = 0; i < 3; i++) {
            setTimeout(function () {
                console.log(i); //3,3,3
            })
        }


        for (let i = 0; i < 3; i++) {
            setTimeout(function () {
                console.log(i); //0,1,2
            })
        }

没有用立即执行函数,那么i会贯穿整个作用域链,而用了之后就会等同于let声明,形成一个独立的作用域,避免全局污染

高阶函数

函数的参数是一个函数,函数内部返回一个函数(满足一个即可) 其实高阶函数用的很多就是,只是不知道名词而已。

常用

比如数组方法map、reduce、filter、sort

好了,以上就是本篇文章的分享,感谢阅读!