4. 函数(重)
4.1 函数基础
函数:一种结构报过一段具备功能性的代码,以便下次使用时直接调用即可(代码复用性)
-
函数结构
function 函数名([参数]){
函数体
[return 返回值]
}
-
访问函数:函数名(参数)
// 案例1:定义一个函数,实现输出一句话输出3次
function sayThree(word){
for(var i=0;i<3;i++){
alert(word);
}
}
sayThree("hello world");
// 案例2:计算两个数之积
function getMul(a,b){
return a*b;
}
console.log(getMul(2,3));
-
函数参数问题
-
参数可以为0个、1个或多个
-
形参和实参问题
- 形参:函数在定义时写的参数,在内存中没有实际的存储空间
- 实参:函数在调用时传递的参数,在内存中就实际存在的
-
局部变量和成员变量
作用域:某一变量/对象/函数的作用范围
- 局部变量:写在函数内部的变量
- 成员变量:写在函数外部的变量
-
默认值参数
- 格式:函数定义时,通过“参数=值”的形式定义
- 默认值参数必须写在普通参数之后
- 调用函数时,可以不用传递默认值参数
- 如果需要改变默认值参数,则使用“参数名(必须与定义时保持一致)= 新值”的形式临时改变默认值
// 默认值参数 function getMul(r,PI=3.14){ return PI*r*r; } console.log(getMul(3));- 值传递和引用传递
- 值传递:给函数参数赋值
- 引用传递:传递参数是传递的内容为引用(对象)
// 引用传递测试 var arr=[1,5,3,4,2]; console.log(arr); function arrSort(arr) { return arr.sort((a,b)=>a-b); } console.log(arrSort(arr));-
函数的参数为函数(函数高阶用法)
将函数对象作为参数传递,且在函数的内部可以执行(函数名())参数函数
// 函数的参数为函数 function testFn(){ alert("hello world"); } function printWord(fn){ fn(); } printWord(testFn);-
arguments 对象
可以通过 arguments 对象获取当前函数的参数
sum(10,22); function sum(a,b){ console.log(arguments); console.log(arguments[0]); console.log(arguments[1]); }
- 函数提升问题:JS在编译时,会检索所有的函数定义,并加载(即使函数定义写在函数下方,也是可以正常执行的)
-
-
函数返回值问题
- 基本函数返回值
- 当函数有返回值时,需要使用 return
- 在调用函数时,需要变量接收 return 返回的返回值
- 函数返回值为函数
// 函数返回值为函数 function test1(){ alert("test1"); } function test2(){ return test1; } var res = test2(); res();- 函数返回值为函数时,返回的内容必须为已定义函数名
- 使用函数时,可以使用任意变量接受返回的函数对象
- 再通过变量()访问返回的函数
- 基本函数返回值
-
函数调用过程
- 实际为 压栈 的过程
- 函数在调用时,会在栈中开辟栈帧,栈帧中存储函数的局部变量,栈帧随函数调用而创建,随函数结束而销毁
- 局部变量生命周期:函数调用时创建,函数结束执行时销毁
-
ES6新特性结构语法
一句话:快速从数组 / 对象中提取值,赋值给变量
- 对象解构(最常用)
- 基础
const user = { name: "张三", age: 18 }; // 解构 const { name, age } = user; console.log(name, age); // 张三 18变量名必须和对象属性名一致
- 设置默认值
const user = { name: "张三" }; const { name, age = 20 } = user; // age不存在,自动取默认值20- 重命名(属性名和变量名不一样)
const user = { name: "张三" }; const { name: username } = user; // 把name属性取出,存入变量username console.log(username);- 函数参数解构(⚠面试高频)
// 传入对象,直接在形参解构 function show({name, age}){ console.log(name, age) } show({name:"李四", age:22})- 数组解构
- 按下标顺序取值,名字随便写
const arr = [10,20,30]; const [a,b,c] = arr; console.log(a,b,c) //10,20,30- 跳过某些项,用逗号占位
const arr = [10,20,30]; const [a,,c] = arr; console.log(a,c) //10,30- 默认值
const arr = [10]; const [a,b=99] = arr console.log(b) //99- 剩余运算符
...rest(只能放最后!)
const arr = [1,2,3,4] const [first, ...other] = arr console.log(other) // [2,3,4]- 字符串也可以解构(当成字符数组)
const str = "abc"; const [x,y] = str; console.log(x,y) // a b⚠️重点坑点
- 对象解构:变量名匹配属性名,和顺序无关;数组解构按顺序,变量名随意
...rest剩余参数只能写在最后,写前面直接报错- 解构
{}开头,单独一行会报错!JS会当成代码块:
// ❌错误写法 {name} = user // ✅要加括号 ({name} = user)- 默认值只有当值为 undefined 的时候才生效,null不会触发默认值
📝面试简答
解构赋值是ES6语法,分为对象解构和数组解构。 对象解构:根据属性名提取属性值;数组解构:按索引顺序提取元素。支持默认值、变量重命名、剩余运算符
...;常用于函数参数快速提取数据,简化代码。📌补充:
...两个身份(区分)- 剩余:解构里
const [a,...rest],收集剩下的值 - 展开:
const arr2 = [...arr1]展开数组(不是解构,容易混)
练习题:
const obj = {id:1, msg:"ok"} const { id, msg:info, type="test" } = obj console.log(id, info, type)输出是什么?
4.2 lambda(箭头函数)及匿名函数
-
匿名函数:无名的函数
- 作用
- 闭包(JS中的重要语法)
- 函数的回调(递归)
- 函数的立即执行
- 作用
- 匿名函数作为参数传递
// 匿名函数
// function setName(){
// return "zhangsan";
// }
function testFn(fn){
alert("user:"+fn());
}
// 参数作为一个匿名函数
testFn(function(){
return "zhangsan";
});
- 匿名函数常见写法①——引用传递过程
var testFn = function(){
alert("lisi");
}
testFn();
- 立即执行的匿名函数(主要作用:创建私有作用域变量,防止变量污染)
(function(){
alert("hello world");
})();
- 箭头函数(lambda):简化函数写法
// 箭头函数
function show(){
alert("hello world");
}
show();
// 1.无参——当函数只有一句代码体,{}可以省略
var show = ()=>{
alert("hello world");
}
show();
// 2.单参——当函数只有一个参数时,()可以省略
var show1 = (username)=>alert("username:"+username);
show1("zhangsan");
// 3.多参
var show2 = (a,b)=>{
alert(a+b);
}
show2(10,20);
// 4.多条语句
var show3 = (a,b)=>{
alert(a+b);
alert(a-b);
}
show3(10,20);
4.3 闭包(closurd)
函数的嵌套中,内部函数访问外部函数的一种结构,内部函数可以访问外部函数定义的变量。
- 条件
- 函数的嵌套
- 内部函数访问外部函数的成员
- 特点
- 内部函数可以访问外部函数的变量或参数
- 外部函数的变量或参数在内部执行完毕后仍然保存在内容中,不被垃圾回收
- 缺点
- 函数的局部变量在调用完没有被及时回收,占用内存时间会变长
- 内存泄漏:没有被回收的变量积攒过多而导致内存溢出
- 积攒过多后会抛出异常
应用
所有数据和功能封装在一个函数的内部(私有作用域),只向外部暴露一个接口
function outer(){
let username="zhangsan";
// 内部函数
function inner(){
alert(username);
}
return inner;
}
var res = outer(); //引用传递
res();
- 将函数的参数传递给内部函数调用
function showDialog(time,msg){
setTimeout(()=>{
alert(msg);
},time);
// 有两个参数,第一个参数为需要执行的函数,第二个参数为执行时间
}
showDialog(2000,"2秒后跳转");
- 可以通过立即执行函数将功能后局部变量私有化,提供外部访问的接口
(() => {
var username="张三";
function showUsername(){
alert("SVIP:"+username);
}
window.myFun = {test:showUsername}
})();
myFun.test();
4.4 递归
eg:画中画、梦中梦、套娃……
函数返回自身的一种技术,主要处理复杂的算法问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>递归函数</title>
</head>
<body>
</body>
</html>
<script>
// 案例:计算阶乘
function factorial(n){
if(n==1){
return 1;
}
return n*factorial(n-1);
}
console.log(factorial(5));
</script>
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/2401_89563276/article/details/166596868




