1、概念:
函数表达了某一种特定的规律,将这种特定的规律用一种方法表达出来就称之为函数.
2、函数的定义:
- 第一种方式
函数声明,使用function关键字,基本格式如:
functin 函数名称 (可选参数1,可选参数2,...){
}
例如:
function hello(){
alert("hello,world!");
}
函数定义完之后,并不会自动执行,需要调用才可以执行函数中的代码.
函数的调用:
函数名(参数),核心就是小括号。
function hello(){
alert("hello,world!");
}
//调用函数
hello();
注*
(1)、定义函数,需要关键字function,关键字之后和函数名需要空格。
(2)、函数名称,和定义变量时规则是一样的.
(3)、大小写区分的,在定义普通函数(目前所学的阶段),首字母使用小写,如果有多个单词,仍然遵循小驼峰命名法则。
(4)、函数名不要以数字开头,可以使用一些特殊符号,如下划线。
(5)、函数名称后面是小括号,必不可少,用来装载形式参数的.
(6)、{}就是函数体,不能少,
- 第二种方式
函数表达式。
let hello=function(){
alert("hello,world!");
}
hello();
注*
(1)、将function整体,放在赋值运算符的右边,作为表达式来使用。
(2)、通过一个变量来引用当前的function,便于后续的调用。
(3)、函数名称可以加上,但是只对函数内部起作用.
将function整体,放在赋值运算符的右边,作为表达式来使用。 通过一个变量来引用当前的function,便于后续的调用。 函数名称可以加上,但是只对函数内部起作用,如图:

在js中,我们把使用声明方式来定义函数的这种用法 —– 函数声明提前。
可以这么来理解,在js中,只要有函数声明,相当于这行代码放在最前面

对于函数表达式这种方式,其实它就是一个变量,只不过我们在赋值的时候,是将函数这种类型的数据赋值给它了。既然是变量,那么就遵循变量的规则,一定要先声明,然后再使用。

3、函数的调用及返回值
(1)、函数调用
*作为函数调用:
自定义函数的调用:function f(){};f();
js提供的内置函数:alert(),parseInt(),parseFloat(),setTimeout等
* 作为方法来调用
将函数定义到某个具体的对象上面,然后通过.语法来进行调用,如:console.log(str);
(2)、函数返回值
函数一定会有返回值。 你调用任何一个函数,都会得到这个函数的返回值,如果这个函数没有写明return,则有一个默认的返回值undefined。
默认情况下,Js函数只能返回一个值。如果你想返回多个值的话,那么你可以使用容器。
通过return返回,返回到函数的调用处。 在函数体中,return后面的代码就不会执行了。return也叫跳转语句。
返回值有
- 返回一个值: a=123; return a;
- 返回多个值:
(1)、使用数组:[1,2,3,"hello",true] 获取某个元素,使用索引。
(2)、使用对象:对象:{name:"wangcai",age:100} name和age叫key,wangcai和100叫value(key:value是成对出现的)
4、函数的参数
形参:函数定义时,()中写的参数,叫形参,相当于函数内部的局部变量,作用是用来接收实参。(相当于函数内部的局部变量)
实参:函数调用时,()中写的参数,叫实参,作用是给函数传递真实的数据,传递过去形参接收了。
let add = function (a, b) {//此处()内的a,b是形参
return a + b;
}
add(1,2);//此处()内的1,2是实参
参数的传递:
基本数据类型的数据(值传递)
就是把栈区的数据copy一份给了形参,形参和实参是一个独立一个内存空间。改变形参,
实参是没有影响。
引用数据类型的数据(引用传递)
就是把栈栈区的地址copy一份给了形参,形参和实参同时指向堆区同一个内存空间。通过
形参改变堆区内存空间的数据,实参这个地址应对的数据也会发生改变。
//基本数据类型参数传递
function f(a){
a = 666;
}
let x = 110;
f(x);
console.log(x) // 110
//引用数据类型参数传递
function f(a){
a = [4,5]
}
let x = [1,2];
f(x);
console.log(x)
console.log(a)
函数可以作为另一个函数的参数:
一个函数可以作为另一个函数的参数,这个函数可以是函数声明,也可以是函数表达式
在JS,我们可以把一个函数声明,作为别一个函数的参数
// 函数表达式
var add = function (a, b) {
return a + b;
}
function compute(f, x, y) {
return f(x, y);
}
console.log(compute(add,1,2))
// 函数声明
function compute(f, x, y) {
return f(x, y);
}
// 函数调用 调用的时候,给它传递了一个函数声明
let rs = compute(function(a,b){
return a + b;
},1,2)
console.log(rs)
arguments:
函数调用的过程就是实参向形参赋值的过程。实参会复制一份给形参,除此之外,它还会给arguments一份。
arguments中收集了实参。
arguments只是函数内部的属性(类数组), 在函数外面是不能访问的。
arguments和形参这间有一一对应的关系:
当形参改变了,那么arguments里面的数据也会改变
当改变了arguments里面的数据,形参也会发生改变
什么时候使用形参,什么时候使用arguments?
1,当实参非常多时,写一堆的形参来接收,不方便,此时你就可以使用arguments
2,当实参有特殊含义时,需要有一个特殊的标识,就可以使用形参来标识。
5、箭头函数
* 省略function关键字
function f(a,b){
return a+b;
}
箭头函数 没有function关键字 =>
var f = (a,b)=>{
return a+b;
}
console.log(f(1,2))
* 如果形参只有1个,()可不写 只有一个形参时,()才能省,其它情况都不省
let f = (a)=>{
console.log(a)
}
let f = a=>{
console.log(a)
}
f(2)
* 如果函数体只有一条语句,{}也可以省,return也需要省。
let f = (a)=>{
return a;
}
let f = (a)=>a;
console.log(f(2))
*如果返回对象,把{} 和 return 省掉的话,需要给这个对象加()
let f = ()=>{
return {name:"wangcai"}
}
let f = ()=>({name:"wangcai"})
console.log(f())
let f = ()=>console.log(123)
f()