函数初相识

86 阅读5分钟

函数的概念

首先一定要明确,和数学中的函数完全是两回事

     在JS中,函数可以理解为 一段在程序(页面)中多次出现的代码段 封装起来的盒子

     简单来说,JS的函数就是一个盒子,盒子里边装的是 在当前页面中 多次出现的 较为复杂的代码段

这5行代码模拟一个较为复杂的功能,它们5个必须在一起才能正常执行

    console.log(100)
    console.log(100)
    console.log(100)
    console.log(100)
    console.log(100)

函数的使用

1.函数的定义(创建一个盒子)

1.1声明式定义

语法:function fn(){}

              function:关键字->表明后续的是一段函数

              fn:函数的名字->将来函数调用的时候需要用到,函数名自定义

            ():内部填写参数->欠着,后续详细的讲解

              {}:内部填写函数调用时要执行的代码段

1.2赋值式定义

语法:var fn=function(){}

2.函数的调用 (使用盒子内的代码)

不管是声明式还是赋值式定义的函数,调用方式都是一样的

调用语法:函数名()/变量名()

声明式与赋值式的区别

1)写法不同

2)调用上略有不同

声明式定义的函数可以在函数定义前去调用

赋值式定义的函数不能在函数定义前去调用

赋值式定义的函数不能在函数定义前去调用的原因:

赋值式定义,其实就是声明一个变量,然后给它赋值为一个函数

在JS中,如果在定义变量之前使用变量的话,那么变量的值为undefined  (变量提升   面试可能会问)

函数的执行结果,一般默认都是undefined  除非手动更改

函数的参数

函数的参数如何书写?--- 书写在function后的小括号内

参数的作用

如果一个函数没有书写参数,那么这个函数的功能相对单一。

如果书写了参数,能够使我们这个函数的使用更加灵活。

参数的书写

(1)function后的小括号内书写的参数叫做 “形参”!!!

     形参的作用:书写之后,相当于在函数内部创建了一个变量,变量实际的值由“实参”传递。

(2)函数名后的小括号内书写的参数叫做“实参”!!!

     实参的作用:将自身的值按照一一对应的关系传递给形参。

函数参数的默认值

函数在创建形参的时候,默认给一个值,将来在调用函数的时候,如果没有传递 那么这个形参的值也不会是undefined  而是给的默认值。

如果传递了对应的值,那么形参的值是实参传递进来的值,否则按照默认值来运行。

函数的返回值

(函数的执行结果)

JS有一个规定:在函数内部创建(定义)的变量,只能在函数内部使用,后续学习作用域的时候,会详细讲解

我们如果想在函数外部得到函数内部的某一个值,或者是运算结果,我们可以通过return这个关键字来帮我们完成

return的注意事项: return具有中断函数的能力,所以一般来说我们将它放在函数的尾部。

函数的预解析

预解析的一个表现就是 声明式函数再定义前可以被调用

    预解析是什么?

    JS在执行代码的时候,会有一个所谓的解析阶段

解析阶段,做了一件事,就是函数提升,就是将声明式函数的定义,提升到当前作用域的最顶端。

作用域的最顶端:暂时理解为当前页面的最开始的位置

浏览器会对我们的JS代码,做一个预解析,预解析的时候,会将函数提升到当前作用域的最顶端(暂时理解为当前页面最开始的位置)

  <script>
fn()  //这行代码是函数调用,所以不需要提升
    function fn() {//这是一个声明式定义的函数,所以需要提升
      console.log('我是fn函数,我被调用了')
    }
    //  预解析之后的代码(执行顺序):
    function fn() {
      console.log('我是fn函数,我被调用了')
    }
    fn()     //所以此时调用的时候,因为fn函数已经定义完成了,所以这里能够正常执行函数
  </script>

作用域

什么是作用域?--- 变量可以起作用的范围

作用域分为两个

1.全局作用域

直接在script内书写的代码)

    在此作用域创建的变量,我们叫做全局变量,在当前script标签内的哪里都能使用

    在JS中,全局作用域中,有一个提前给我们准备好的对象(一种数据格式,后续会详细讲解)  这个对象叫做window

2.局部作用域

(在JS中,只有函数能够创建局部作用域)

在此作用域创建的变量,只能在当前作用域使用,超出这个作用域(也就是在函数外边)去使用,就会找不到变量

作用域链

(这是一个纯概念性的东西,面试也可能会问)

作用域就是在访问一个变量的时候,如果当前作用域内没有,会去自己的父级作用域,也就是上一层作用域内查找,如果找到直接使用,如果没有找到继续向上层查找

直到查到最顶层的作用域,如果找到了直接使用,如果没找到,报错提示变量不存在(未定义)

我们将这个一层一层向上查找的规律,叫做作用域链

作用域链的赋值规则

在给变量赋值的时候,首先会去当前作用域内查找该变量,如果有,直接赋值;

如果没有,会去自己的父级查找,在父级找到直接修改值然后停止查找,如果没有继续向自己的父级查找,知道知道全局作用域

在全局作用域内,知道直接赋值修改他的值,如果没有找到,那么在全局作用域创建一个变量,并赋值

递归函数

本质上还是一个函数

当一个函数在函数的内部调用了自身,那么就算是一个所谓的递归函数(只不过有点小缺陷)