JS函数

377 阅读6分钟

JS函数的概念

函数就是把特定功能的代码抽取出来,使之成为程序中的一个独立实体

函数的作用

正如函数的概念, 我们可以根据需要, 将特定的功能用函数来包裹(封装)

使用函数的好处

  1. 函数可以在同一个程序或其他程序中多次重复使用(通过函数名调用)
  2. 使程序变得更简短而清晰 , 提高可读性
  3. 有利于程序维护

函数的分类

函数可以分为: 系统函数(内置函数) 和 自定义函数

系统函数(内置函数)

是官方提供好的函数,可以直接使用

alert(); //信息提示弹窗
var res = prompt("请输入一个数") //带有输入框的弹窗,res可接收输入的值
var res = confirm("您确定要删除吗?");//确认框,res接收true或false
print();//打印页面
document.write();//将内容写入前端页面
console.log();//将内容输出到控制台
isNaN();//是否为非数值类型
parseInt();//转换为整型
parseFloat();//转换为浮点型
Number();//转换为数值类型
Boolean();//转换为布尔类型
toString();//转换为字符串
toFixed();//保留小数点后几位  四舍五入
// ...

自定义函数

是用户自己定义的函数, 用户可以根据实际需求, 对特定的功能使用函数来封装
函数的定义有三种写法:普通写法、匿名函数和构造函数创建函数

函数定义及调用——普通写法

定义函数的语法格式:
function 函数名([形参1,形参2,……]) {
代码块;
}
调用函数的语法格式:
函数名([实参1,实参2,……])

function calc(num1, num2) {
    var res = num1 + num2;
    return res;
}

var result = calc(100, 200);//可以在定义函数的前面或后面调用

console.log(result);

7a33c103d5a44b5913d03c642d78a3e.png

函数定义及调用——匿名函数

定义函数的语法格式:
var 变量名 = function([形参1,形参2,……]) {
代码块;
}
调用函数的语法格式:
变量名([实参1,实参2,……])

var calc = function (num1, num2) {
    var res = num1 + num2;
    return res;
}

var result = calc(100, 200);//必须在在定义函数后面调用

console.log(result);

函数定义及调用——构造函数创建函数

定义函数的语法格式:
var 变量名 = new Function([形参1,形参2,……],代码块);
调用函数的语法格式:
变量名([实参1,实参2,……])

// new Function的最后一个参数,是函数的代码体
var calc = new Function("num1", "num2", "return num1+num2");
var result = calc(100, 200);//必须在在定义函数后面调用
console.log(result);

函数中的arguments数组

JS中函数不介意传递进来多少个参数,也不在乎传进来参数是什么数据类型,在调用函数时也未必一定要传递指定数量的参数,原因是 ECMAScript 中的参数在内部是用一个数组(arguments)来表示的。函数接收到的始终都是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。

arguments 参数
1.它是一个伪数组,有下标,不具备数组的方法
2.它只能在函数内部出现
作用:动态接受实参

// 例,写个函数计算所有传入参数相乘的结果(参数数量不定)
function fn1(){
    var res=1;
    for(var i=0;i<arguments.length;i++){
        res*=arguments[i];
    }
    return res;
}
console.log(fn1(1,2,3));//6
console.log(fn1(1,2,3,4));//24
console.log(fn1(1,2,3,4,5));//120

作用域

作用域: 就是起作用的范围,或者说有效范围。
 1).变量在函数内部的是局部的
 2).变量在函数外部的是全局的
作用域链:当函数内部访问某一个变量的时候,首先去函数内部查找,如果内部没有,就向外层函数查找,如果外层函数,没有就向(浏览器向window)全局在nodejs是向(global)上查找,这个"查找的过程"就叫做"作用域链"。

var a=100;//全局变量a
var c=150;//全局变量c
function fn1(a){//局部变量a
    a=50;//改变的是局部变量a
    var b=200;//局部变量a
    console.log(a);//50 
    console.log(c);//150
    console.log(b);//200
}
fn1();
console.log(a);//100 
console.log(c);//150
console.log(b);//报错 b is not defined 这个地方已经超过了变量b的有效范围无法调用

局部变量

局部变量定义在函数内部的变量,这个变量只能在函数内部使用,即作用域范围只是函数内部,另外,形参也是局部变量。

function fn(){
    var a=100;
    console.log(a);//100
}
fn();
console.log(a);//找不到变量a,因为a是在函数内部定义的局部变量,会报错 a is not defined

全局变量

全局变量就是定义在函数外部的变量,这个变量在任何函数中都有效,即作用域范围是当前文件的任何地方。

【注意】: 在定义变量时, 如果不写关键字var也是合法的, 且是全局变量, 但是这样写不安全,容易在其他地方被更改, 所以我们在函数中写变量要加上var

function fn() {
    //在函数内部,使用var关键字,声明的变量是局部变量
    //在函数内部,没有使用var关键字,声明的变量是全局变量
    var a = b = 100;
    console.log(b);//100
    console.log(a);//100
}
fn();
console.log(b);//100
console.log(a);//报错 a is not defined

函数嵌套

函数的嵌套: 函数内部可以再包含其他函数;
函数之间允许相互调用,也允许向外调用, 但是不可以调用同级函数的嵌套函数;

function fn1() {
    console.log("-----------");
    console.log("函数1");
    //函数之间相互调用
    fn2();//函数2
    //不可以调用同级函数的嵌套函数
    fn3();//报错 fn3 is not defined
}
var flag=true;//设置一个让内部的fn3只能调用一次fn2的变量
function fn2(){
    console.log("-----------");
    console.log("函数2");
    //函数内部可以再包含其他函数
    function fn3(){
        console.log("函数3");
        if(flag){
            flag=false;//修改为false后不再会进入此代码块,没有这一句将会是死循环
            //函数向外调用
            fn2();//函数2
        }
    }
    fn3();
}
fn2();
fn1();

控制台输出:

image.png

递归调用

函数可以自己调用自己,必须要有结束条件(有临界点),称为函数的递归调用

递归调用的方式

  1. 首先去找临界值,即无需计算,获得的值(一般是返回该值)。
  2. 找这一次和上一次的关系(一般从后往前找)
  3. 假设当前函数已经可以使用,调用自身计算上一次的运行结果,再写出这次的运行结果。

例题一 5的阶乘是多少?

function fn(n) {
  if (n == 1) {
    return 1;
  }
  return n * fn(n - 1);
}
console.log(fn(5));

例题二 兔子繁殖问题

// 兔子繁殖问题,设有一只新生兔子,从第四个月开始他们每个月, 月初都生一只兔子,
// 新生的兔子从第四个月月初开始又每个月生一只兔子按此规律,并假定兔子没有死亡,
// n(n<=20)个月月末共有多少只兔子? 

// 月份  1个月大小  2个月大小    3个月大小   4个月大小   总计
//  1      1        0         0        0       1
//  2      0        1         0        0       1
//  3      0        0         1        0       1
//  4      1        0         0        1       2
//  5      1        1         0        1       3
//  6      1        1         1        1       4
//  7      2        1         1        2       6
//  8      3        2         1        3       9
//  9      4        3         2        4       13
//  10     6        4         3        6       19
//  .
//  .
//  20 ?

//临界条件 n<4 
//规律:fn(n)=fn(n-1)+fn(n-3)

function fn(n){
    if(n<4){
        return 1;
    }
    return fn(n-1)+fn(n-3);
}
console.log(fn(20));//872