🌟前言
哈喽小伙伴们,本文将收录在JavaScript【前端童子功】这个专栏里;这个专栏里边会收录一些JavaScript的基础知识和项目实战;希望大家可以多多支持,你们的支持就是我创作的动力;让我们一起来看看吧🤘
🌟什么是函数?
函数:将完成某一特定功能的代码封装起来,并且可以重复调用的代码块。
为何使用函数?
- 能够对代码进行复用:只要定义一次代码,就可以多次使用它。
- 能够多次向同一函数传递不同的参数,以产生不同的结果。
- 使程序更加简洁、具有逻辑性、维护方便
🌟函数声明方式
🌟 function关键字
function 函数名([参数1],[参数2],...[参数n]){ 函数体 [retrun] //返回值 }
🌟 字面量定义(匿名函数)
var 变量 = function ([参数1],[参数2]....){ 函数体 [retrun] //返回值 }
🌟 实例化构造函数
var 变量 = new Function([参数1],[参数2]...,"函数体");
//实例化构造函数--例二 function Animal(name,sex,age){ this.name=name; this.sex=sex; this.age=age; this.eat=function(eat){ return "骨头" } } var animal1=new Animal("狗","男","20","骨头"); console.log(animal1); var animal2=new Animal("猪","母","5"); console.log(animal2); var animal3=new Animal("猫","公","18"); console.log(animal3); console.log(animal2.name); console.log(this); // 例三 function Person(name,age){ this.name=name; this.age=age; this.play=function(){ return "猫"; } } var zs=new Person("zs","20") console.log(zs); var ls=new Person("ls","18") console.log(ls);
🌟函数调用方式
🌟通过括号调用
用于具名函数的调用
- 函数名()
- 变量名()
function fun1(){} fun1() var fun2 = function (){} fun2()
🌟自调用(IIFE)
用于匿名函数的调用,匿名函数还可以通引用变量来调用。
//第一种 (function (){ //函数体; })() //第二种 !function(){ //函数体; }() //第三种 (function(){ //函数体; }())
注意: 在进行函数自调用时,上一条语句必须结尾有;
🌟通过事件调用
<script> function fun(){} </script> <div onclick="fun()"></div>
🌟注意事项
创建/调用函数注意问题:
- 如果两个函数的命名相同,后面的将会覆盖前面的函数。
- 以function声明的函数可以前置调用,以字面量方式声明方式后置调用。
- 在不同的
<script></script>
块中声明函数,声明之后块中调用。
🌟函数声明覆盖
如果两个函数的命名相同,后面的将会覆盖前面的函数。
function bb(){ alert("这是第一个声明"); } function bb(){ alert("这是第二个声明"); } bb(); //结果为 “这是第二个声明
🌟函数调用顺序
以基本语法声明的函数,会在页面载入的时候提前解析到内存中,以便调用。所以可以在函数的前面调用。但是以字面量形式命名的函数,会在执行到他的时候,才进行赋值。所以只能在函数的后面调用。
aa(); // 结果为 弹出 1 function aa(){ alert(1) } aa(); // 结果为 弹出 1 aa(); // 报错 aa is not a function var aa = function(){ alert(1) } aa();
🌟 函数在不同块调用顺序
在不同的<script></script>
块中,因为浏览器解析的时候是分块解析的,所以前面的块不能调用后面块的函数,所以在不同的块之间调用函数的时候,应该先声明后调用。
<script> aa(); //报错 </script> <script> function aa(){ alert(1) } </script> <script> aa() //结果为 弹出 1 </script>
🌟箭头函数
ES6标准新增了一种新的函数:Arrow Function(箭头函数)。
🌟 箭头函数语法
箭头函数表达式的语法比普通函数表达式更简洁。
(参数1, 参数2, …, 参数N) => { 函数声明 } (参数1, 参数2, …, 参数N) => 表达式(单一) // 相当于:(参数1, 参数2, …, 参数N) =>{ return 表达式; }
当只有一个参数时,圆括号是可选的:
(单一参数) => {函数声明} 单一参数 => {函数声明}
没有参数的函数应该写成一对圆括号:
() => {函数声明}
🌟函数的参数
可以动态的改变函数的变量的类型与值,使同一函数实现不同的效果
当我们封装一个功能,例如十行十列表格,但是每次使用该功能时想动态改变实现效果,例如想输出为五行五列、两行两列的表格,这时就需要修改函数体代码。 而更好的方法就是,在调用时有使用者传入一些值来控制函数体中的相关功能,即可实现不同效果,这个使用者在调用函数时传入的值就是函数的参数。
🌟 参数作用
可以动态的改变函数的变量的类型与值,使同一函数产生不同的结果。
🌟 参数类型
形参:函数在定义时,括号里所定义的变量。 (形式上存在,只有在被调用时才有值)
实参:函数在调用时,括号里所传入的值。 (进行函数调用时,它们都必须具有确定的值, 以便把这些值传送给形参)
// num 是形参 function ta(num){ for(var i = 1;i <= num;i++){ for(var j = 1;j <= num-i;j++){ document.write(" "); } for(var k = 1;k <= i*2-1;k++){ document.write("*"); } document.write("<br>"); } } ta(6); // 6 是实参
在实参为形参传递过程中,实参和形参位于内存中两个不同地址中,实参先自己复制一次拷贝,再把拷贝复制给形参。所以,在函数体中,形参的变化不会对实参有任何的影响。例如:
var number = 10 function fun(number){ number = 100 } fun(number); alert(number); // 10
🌟 参数详解
- 参数可以是任何的数据类型
- 参数个数
- 参数尾逗号
🌟 参数数据类型
参数可以是任何的数据类型
function TYPEOF(type){ alert(typeof type); } TYPEOF(1) TYPEOF("a") TYPEOF(true) TYPEOF(null) TYPEOF() //甚至可以传入函数: TYPEOF(function(){alert(1)})
🌟 参数个数
- 实参与形参的个数相同时,一一对应。
- 实参小于形参时,形参自动赋值为undefined。
function aa(a,b){ alert(a); alert(b); } aa(1); // 1 undefined
实参大于形参时,使用
arguments
对象来获取。
function aa(a,b){ alert(a); alert(b); alert(arguments.length); alert(arguments[2]); alert(arguments.callee); } aa(1,5,7); //依次弹出 1 5 3 7 函数本身
arguments对象 在创建函数时,隐式的创建了arguments对象,它是用来记录函数的参数的信息的,只能在函数内部使用
它的属性:
- length: 函数的参数的长度
- callee: 对函数本身的调用
- 可以通过下标来访问具体参数的值。
注:arguments
对象不是数组,而是一个类似数组的对象。所以为了使用数组的方法,必须使用Array.prototype.slice.call
先将其转为数组。
- [es6]rest参数
ES6 引入 rest 参数(形式为…变量名),用于获取函数的多余参数,这样就不需要使用arguments
对象了。rest
参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
function fun(...a){ console.log(a); // [1,2,3,4] } fun(1,2,3,4) function fun(a, ...b){ console.log(a,b); //1 [2,3,4] } fun(1,2,3,4) // rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。 function f(a, ...b, c) { // 报错 }
🌟 参数尾逗号
在ES7种,函数实参和形参末尾可以以逗号结束:
function fun(a,b,){ } fun(10,20,)
功能:重新排列元素项,改变最后一个元素位置时不需要增删逗号
🌟函数的重载
一个函数通过传入的参数的个数不同或者参数类型的不同,可以对应函数的多个实现,而且每一种实现对应一个函数体。
重载函数常用来实现功能类似而所处理的数据类型不同的问题。
模拟函数的重载:
function fun(a,b){ if(arguments.length == 1){ alert("只有一个参数"+a); } if(arguments.length == 2){ alert(" 有两个参数"+a+"和"+b); } if(arguments.length >= 3){ alert("参数太多了"); } } fun(1,3.4,4);
🌟函数参数默认值
// 该函数计算两数之和,但如果调用只传入一个参数则结果是NaN,所以必须为参数设置默认值0 function add(a,b){ return a+b }
🌟ES5设置默认值方式
使用短路原则为变量设置默认值
// 利用短路原则为函数参数设置默认值,参数存在则取参数,参数未传则取0 function add(a,b){ a = a||0; b = b||0; return a+b } // 为变量设置默认值1 var num = num || 1
🌟ES6函数参数设置默认值
ES6允许为函数的参数设置默认值,即直接写在参数定义的后面。
function add(x, y = 0) { console.log(x, y); } log(10) // 10 0 log(10, 100) // 10 100 log(10, '') // 10
🌟 函数的length属性
函数的length属性,将返回没有指定默认值的参数个数,仅包括第一个具有默认值之前的参数个数。
function aa(a){} function bb(a=5){} function cc(a,b,c=5){} console.log(aa.length) // 1 console.log(bb.length) // 0 console.log(cc.length) // 2
🌟函数返回值:在函数调用的地方相当于函数的返回值
函数体中的计算结果可以输出查看,但是如果想对函数的结果进行处理则需要用到函数的返回值。
函数体中的关键字 return
可以将函数体中运行的结果返回给函数外部:
function fun(a,b){ var num = a+b; return num; } var end = fun(1,2); // 函数运行结果保存到变量end中
🌟return 的功能
- 将函数运行结果返回
- 停止并跳出当前函数 (不会执行return后面的语句)
function aa(){ return; alert("hello world"); } aa(); // 没有弹出 hello world
一个函数可以有多个return语句,但只有一个return执行(常用于判断)
function aa(a){ if(a>0){ alert(a); return; } if(a<=0){ alert(a); return; } } aa(3); // 3
🌟 函数返回值使用事项
- 返回值可以是任何数据类型
- 每个函数都默认有返回值,如果一个函数没有写
return
,会默认返回undefined
。
function aa(a){ if(a>0){ alert(a); return; } if(a<=0){ alert(a); return 1; } } alert(aa(3)); // 3 undefined alert(aa(0)); // 0 1
一个函数只能有一个返回值。
function bb(a,b,c){ return a,b,c; } alert(bb(3,5,7)); // 7
原因:用逗号做返回值时,是按从左到右赋值的,最终赋值为最后一个值,前面的值被覆盖了。
如果想返回多个值,则可以将多个值打包为数组或对象
🌟写在最后
更多JavaScript知识以及API请大家持续关注,尽请期待。各位小伙伴让我们 let’s be prepared at all times!