函数的使用
函数的类型
function result() {}
console.log(typeof result); // function
定义 ( 声明 ) 函数
function name(params) {}
name
:自定义的函数名。params
:函数的形式参数,简称形参;用于接收实参传递过来的数据;参数之间用,
隔开。
function add(num1, num2) {
console.log(num1 + num2);
}
函数的形参仅能在函数内使用,为局部变量。
- 函数内部不能再用
let
定义同名变量:
function show(age = 18) {
let age = 20; // SyntaxError: Identifier 'age' has already been declared
}
- 如果用
var
定义同名变量,变量值会覆盖形参值:
function fn(a) {
var a = 10;
console.log(a); // 10
}
fn(1);
如果重复定义函数,后定义的函数体会覆盖先定义的函数体
function operateData(a, b) {
return a + b;
}
function operateData(a, b) {
return a - b;
}
console.log(operateData(2, 1)); // 1
调用函数
name(params);
params
:函数的实际参数,简称实参;用于给函数传递需要的数据。
function add(num1, num2) {
console.log(num1 + num2); // 3
}
add(1, 2);
参数的传递
- 形参和实参的位置顺序要对应。
- 形参的类型就是实参的类型,实参的类型由实参值决定。
function add(num1, num2) {
console.log(num1 + num2);
}
add(1, 2); // 3 传数字,进行数字相加
add('1', 2); // 12 传字符串,进行字符串拼接
- 如果传入的是引用类型数据,则操作的是内存地址
function fun(obj) {
obj.name = 'superman'; // 操作原来的内存地址
obj = new Object(); // 覆盖原来的内存地址
obj.name = 'monster'; // 操作新的内存地址
}
const person = new Object();
fun(person); // 传入的是内存地址
console.log(person.name); // superman
参数的个数
- if 形参数 = 实参数:
function fun(hobby1, hobby2, hobby3) {
console.log('i like', hobby3, hobby1, hobby2); // i like playing eating sleeping
}
fun('eating', 'sleeping', 'playing');
- if 形参数 > 实参数:没有实参赋值的形参值是
undefined
。
function fun(hobby1, hobby2, hobby3) {
console.log('i like', hobby3, hobby1, hobby2); // i like undefined eating sleeping
}
fun('eating', 'sleeping');
- if 实参数 > 形参数:没有形参接收的实参会被忽略。
function fun(hobby1, hobby2) {
console.log('i like', hobby1, hobby2); // i like eating sleeping
}
fun('eating', 'sleeping', 'playing');
arguments 对象
函数内部自带一个类数组对象 arguments
,以 key-value 的形式存储着所有的实参。
- 类数组对象具有类似于数组的结构,它们有从 0 开始的索引和
length
属性,可以通过索引访问元素。 - 与真正的数组不同,类数组对象没有数组对象上的内置方法(如
push()
、pop()
、slice()
等)。 - 类数组对象通常实现了迭代器接口,可以使用
for...of
循环或迭代器方法(如Array.from()
、Array.prototype.map()
)对其进行迭代。
function fun(hobby1, hobby2) {
console.log(arguments); // Arguments(3) ["eating", "sleeping", "playing" ... ]
console.log(arguments[0]); // eating
console.log(arguments[2]); // playing
}
fun('eating', 'sleeping', 'playing');
形参名是 arguments
对应索引位置的别名。如果修改形参值,arguments
对应位置的值也会改变,反之同理。
function fun(hobby1, hobby2, hobby3) {
console.log(arguments[0]); // eating
hobby1 = 'drinking'; // 修改指定形参名的参数值
console.log(arguments[0]); // drinking
}
fun('eating', 'sleeping', 'playing');
模拟 “函数重载”
函数重载是指在同一个作用域中定义多个具有相同名称但参数个数或类型不同的函数。
- JS 中并不直接支持函数重载,但可以通过一些技巧模拟函数重载的效果,实现相似的功能。
arguments.length
可以返回类数组对象的长度。这样我们就可以根据实参数的不同,来制定不同的功能代码。
function fun() {
switch (arguments.length) {
case 1:
console.log('i like', arguments[0]);
break;
case 2:
console.log('i like', arguments[0], arguments[1]);
break;
case 3:
console.log('i like', arguments[0], arguments[1], arguments[2]);
break;
}
}
fun('studying'); // i like studying
fun('writing', 'reading'); // i like writing reading
fun('eating', 'sleeping', 'playing'); // i like eating sleeping playing
可以使用 arguments 对象实现一个累加器:
function sum() {
// 形参写不写、写多少个都没关系
let result = 0;
for (let i = 0; i < arguments.length; i++) {
// 这里用的是 arguments.length 所以可以没形参
result += arguments[i];
}
console.log(result);
}
sum(1, 2, 3, 4); // 实参数可以任意设置 (0, infinity)
返回值
- 函数可以通过
return
语句来返回内容。函数内,程序执行到return
会立即返回结果,并结束函数。 - 函数可以接收多个参数,但只能返回一个值
function sum() {
return 10; // 返回 10,并结束函数
console.log(11); // return 后面的语句不会被执行
}
let a = sum();
console.log(a); // 10
函数也可以返回一个空值,这样得到的返回值为 undefined
:
function fun() {
return; // 返回一个空值
}
console.log(fun()); // undefined
返回空值相当于不写 return
语句,返回值为 undefined
function fun() {}
console.log(fun()); // undefined