函数

18 篇文章 1 订阅
2 篇文章 0 订阅


前言

这部分来学习函数的知识,要做到学以致用啊!


一、函数

函数,也叫作功能、方法,可以将一段代码封装起来,封装起来的代码具有一定的功能,内部封装的代码具有完整的结构体,要执行就都执行,要不就都不执行。(作用:封装一段代码,将来可以重复使用)。

1.函数的声明和调用

函数的声明又叫做函数的定义,先定义才能使用。函数调用:函数名() ,函数内部语句执行的位置,与定义位置无关,与调用位置有关。

//声明函数
function fun() {
    console.log(1);
    console.log(2);
    console.log(3);
    console.log(4);
}
console.log(5);
//调用函数
fun();

2.函数的参数

接口:就是函数的参数,函数参数的本质就是变量,可以接收任意类型的数据,导致函数执行结果根据参数不同,结果也不同。
一个函数可以设置0个或者多个参数,参数之间用逗号分隔。
形式参数:定义的()内部的参数,叫做形式参数,本质是变量,可以接收实际参数传递过来的数据。简称形参。
实际参数:调用的()内部的参数,叫做实际参数,本质就是传递的各种类型的数据,传递给每个形参,简称实参。
在这里插入图片描述
代码如下(示例):

//定义一个求和函数。函数里面传入两个数据
//参数:传入两个参数,数据类型为数字
//功能:得到两数之和
function sum(a,b) {
    console.log(a+b);
}
//调用函数,括号内添加数据。
sum(5,7);
sum("3",7);

3.函数的返回值

函数能够通过参数接收数据,也能将函数的执行结果返回一个值。利用函数内部的一个关键字return设置函数的返回值。
函数如果有返回值,执行结果可以当成普通数据参与程序。函数如果有返回值,可以作为一个普通数据赋值给一个变量,甚至赋值给其他函数的实际参数。
注意:如果函数没有设置return语句,那么函数有默认的返回值undefined;如果函数使用return语句,但是return后面没有任何值,那么函数的返回值也是 undefined。
代码如下(示例):

//定义一个求和函数。函数里面传入两个数据
//参数:传入两个参数,数据类型为数字
//功能:得到两数之和
function sum(a,b) {
   return a+b;
}
//调用函数
console.log(sum(5,7));
//把函数的返回值赋给一个变量
var he = sum(2,4);
console.log(he);
//把函数的返回值赋给一个函数
console.log(sum(2,sum(3,4)));
//return可以终止函数执行
// function fun() {
//     console.log(1);
//     console.log(2);
//     console.log(3);
//     return;
//     console.log(4);
// }
// fun();

4.函数表达式

函数表达式是定义函数的另一种方式,就是将函数的定义、匿名函数(函数没有函数名)赋值给一个变量。

//定义一个函数表达式
var gai = function fun() {
    console.log(1);
};
var gai2 = function() {
    console.log(2);
};
//调用的时候,调用函数名不成功,只能调用变量名加括号。
// fun();
gai();
gai2();

5.函数的数据类型

函数是一种数据类型,是function(属于object),可以作为其他函数的参数,将函数当成另一个函数的返回值。

function fun() {
    console.log(1);
}
var gai = function() {
    console.log(2);
}
//检测函数的数据类型
console.log(typeof(fun));
console.log(typeof(gai));

//函数是一种数据类型,可以作为其他函数的参数
setInterval(function() {
    console.log(1);
},1000);

//将函数当成另一个函数的返回值
function di(a) {
    var b = 3;
    return function() {
        alert(a+b);
    };
}

6.arguments对象

arguments对象是一个比较特别的对象,实际上是当前函数的内置属性,也就是所有函数都内置了arguments对象,arguments存储了所有的实参,是一个伪数组,可以进行遍历。

function sum(a,b) {
    return a+b;
}
//实参的个数可以与形参的个数不一样
console.log(sum(1,2));
console.log(sum(1));
console.log(sum(1,2,3,4));

//arguments可以接收所有的实参
function fun() {
    console.log(arguments);
    console.log(arguments.length);
    //遍历数组内的实参
    for (var i = 0 ;i < arguments.length ;i++) {
        console.log(arguments[i]);
    }

}
fun(1,2,3,4,5,6);

案例
定义一个求和函数,如果传入1个参数,返回它自己,如果传入两个参数,返回他们的和,如果传入三个参数,先比较前两个的大小,大的与第三个参数求和返回,如果传入4个及以上,输出错误提示。

function sum(a,b,c) {
    //条件分支语句,根据实参的个数不同来判断分支
    switch (arguments.length) {
        case 1:
            return a;
            break;
        case 2:
            return a + b;
            break;
        case 3:
            return a > b ? a + c : b + c;
            break;
        default:
            //模拟控制台报错
            throw new Error("参数不能超过三个!");
    }
}
//调用函数
console.log(sum(1));
console.log(sum(1,2));
console.log(sum(1,2,3));
console.log(sum(1,2,3,4,5));

7.函数的递归

函数的内部可以通过函数名调用函数自身的方式,就是函数的递归现象。(递归的次数太多容易出现错误,超出了计算机的计算能力)

//函数,如果传入的参数是1,那么返回1,如果输入的是其他数,那么返回参数+函数调用上一项
function fun(a) {
   if (a === 1) {
       return a;
   } else {
       return a + fun(a-1);
   }
}
console.log(fun(1));
console.log(fun(2));
console.log(fun(3));
console.log(fun(4));
// console.log(fun(100000000000));

斐波那契数列案例

//斐波那契数列
//参数:正整数
//返回值:对应正整数位置的菲波那切数列
function fibo(a) {
    if (a ===1 || a === 2) {
        return 1;
    } else {
        return fibo(a-1) + fibo(a-2);
    }
}
//调用函数
console.log(fibo(1));
console.log(fibo(2));
console.log(fibo(3));
console.log(fibo(4));

二、作用域

作用域:变量可以起作用的范围。
如果变量定义在一个函数内部,只能在函数内部被访问到,在函数外部不能使用这个变量,函数就是变量定义的作用域。
局部变量:定义在函数内部的变量,只能在函数作用域内部被访问到,在外面没有定义的。全局变量:从广义上来说,也是一种局部变量,定义在全局的变量,作用域范围是全局,在整个js程序任意位置都能够被访问到。

var a = 0;
//定义一个函数
function fun() {
    var a = 1;
    console.log(a);
}
//调用函数
fun();
console.log(a);

1.参数和函数的作用域

函数的参数本质是一个变量,也有自己的作用域,函数的参数也是属于函数自己内部的局部变量,只能在函数内部被使用,在函数外面没有定义。
函数也有自己的作用域,定义在哪个作用域内部,只能在这个作用域范围内被访问,出了作用域不能被访问的。
函数定义在另一个函数内部,如果外部函数没有执行时,相当于内部代码没写。

//函数的参数是局部变量
function fun(a) {
    var a = 1;
    console.log(a);
}
fun(1);
// console.log(a);

// 函数也有自己的作用域
function outer() {
    var a = 1;
    function inner() {
        console.log(2);
    }
    inner();
}
outer();
// inner();

2.作用域链和遮蔽效应

作用域链:创建一个函数就会有一个新的作用,如果函数中还有函数,那么这个作用域中就还有作用域。函数内指向函数外的链式结构就是作用域链。
遮蔽效应:程序在遇到一个变量时,使用时作用域查找顺序,不同层次的函数内都有可能定义相同名字的变量,一个变量在使用时,会优先从自己所在层作用域查找变量,如果当前层没有变量定义会按照顺序从本层往外依次查找,直到找到第一个变量定义。整个过程中会发生内层变量遮蔽外层变量的效果,叫做“遮蔽效应”。

//定义一个全局变量
var a = 1;
//定义一个外层函数
function outer() {
    var a = 2;
    //定义一个内层函数
    function inner() {
        var a = 3;
        console.log(a);
    }
    inner();
}
outer();

三、其他

1.不写var关键字的影响

在函数内部想要定义新的变量,如果不加关键字var,相当于定义的全局变量。如果全局也有相同的标识符,会被函数内部的变量影响,局部变量污染全局变量。
注意:每次定义变量时都必须写var关键字,否则就会定义在全局,可能污染全局。

2.预解析

1.把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值
2.把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用.
3.先提升var,再提升function。
提升过程中,只提升声明过程,不提升变量赋值,相当于变量定义未赋值,变量内存储undefined值。

在预解析过程中,所有定义的函数,都会将声明的过程提升到所在的作用域最上面,仕将来的代码执行过程中,按照先后顺序会先执行被提升的函数声明过程。
在预解析之后的代码执行过程中,函数定义过程已经在最开始就会执行,一旦函数定义成功,后续就可以直接调用函数。
因此,在js 中会出现一种现象,在前面调用后定义的函数,不会报错,而且能正常执行函数内部的代码。
函数声明提升可以用于调整代码的顺序,将大段的定义过程放到代码最后,但是不影响代码执行效果。

//预解析,把变量函数声明提升到了最顶部
console.log(a);
var a = 1;

fun();
function fun() {
    console.log(3);
}

3.IIFE自调用函数

叫做即时调用的函数表达式,表示函数定义时就调用。如果能将函数矮化成表达式,那么后面加上()就可以立即执行。
函数矮化成表达式的方法,可以让函数参与一些运算,也就是说给函数前面加一些运算符。
数学运算符:±()
逻辑运算符:!非运算
lIFE结构可以关住函数的作用域,在结构外面是不能调用函数的。lIFE最常用的是()运算符,而且函数可以不写函数名,使用匿名函数。

//关键字定义的函数方式,不能立即执行
function fun() {
    console.log(1);
}
//函数表达式方式,可以在定义时立即执行
var foo = function() {
    console.log(2);
}();

//通过在函数前面添加操作符,可以将函数矮化成表达式
+ function fun() {
    console.log(3);
}();
- function fun() {
    console.log(4);
}();
( function fun() {
    console.log(5);
} )();
! function fun() {
    console.log(6);
}();

//IIFE关住了函数作用域,在外面是调用不函数的,这样只能自调用一次。
fun();

//常用的IIFE结构
( function fun(a) {
    console.log(a);
} )(4);

总结

函数这部分就学习完了,下一部分学习对象,JavaScript在前端里面是很重要的一个模块,一定要多多练习啊。
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值