4. 函数
4-1. 函数的定义
4-1-1. 声明式定义
function 函数名(形参1,形参2,....){ 函数体 .... return }
函数名需要满足标识符命名规则
4-1-2. 字面量 式定义
4-2. 函数的调用
var res = 函数名(实参1,实参2,.....)
函数定义时,return 什么 res的结果就是什么,如果没有return, res的值是undefined
4-3. 函数的返回值
return 什么 res的结果就是什么,如果没有return, res的值是undefined
4-4. 基本数据类型和引用数据类型区别
基本数据类型存的是值
引用数据类型存的是堆内存地址
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C3nNpfUi-1681398026369)(js%E5%9F%BA%E7%A1%80.assets/image-20230325143151411.png)]
4-5. 全局作用域-局部作用域-全局变量-局部变量
全局作用域:window
局部作用域:函数调用的执行栈内存就是局部作用域
全局变量:
- 在全局中定义的变量,不管用没用var声明,都是全局变量,会出现在window对象身上
- 在局部作用域中,没有使用var声明的变量,也是全局变量
局部变量:
- 函数的形参是局部变量
- 局部作用域中,使用var声明的变量是局部变量
4-6. 作用域链
var a = 100; function f1(){ var a = 200; function f2(){ var a = 300; function f3(){ var a = 400; console.log(a); } f3(); } f2(); } f1();
4-7. 小结:
-
为什么要用函数?
将需要多次使用的,相同的业务逻辑的代码进行封装[函数],方便复用。
-
怎么定义?
function fn(形参){ return } fn(实参)
- 形参相当于函数的私有变量[局部变量]
- 实参是字面量,会按照位置关系,一一对应传递给形参
- return 返回值。return 什么,函数执行的结果就是什么?如果没有return ,值是undefined
-
作用域:
- 全局作用域:window
- 局部作用域:函数执行的执行栈内存,就是该函数的局部作用域
-
全局变量和局部变量
- 全局变量:最终都会出现在window身上
- 怎么定义全局:
- 在全局声明的变量,不管用不用var都是全局变量
- 在局部作用域中,没有使用var声明的变量
- 怎么定义全局:
- 局部变量:只在当前作用域及下级作用域有效
- 函数的形参是局部变量
- 函数内使用var声明的变量是局部变量
- 全局变量:最终都会出现在window身上
-
作用域链:在局部作用域中,沿着上级作用域查找变脸的机制,叫做作用域链
- 上级作用域怎么确定? 函数在谁身上定义的,谁就是上级作用域
-
回调函数:函数的参数是一个函数,该参数函数会在当前函数中被调用
4-8. 闭包
怎么会产生闭包:
函数嵌套函数,内部函数的引用地址被外部变量接收,就会产生闭包
什么是闭包:能够读取其他函数内部变量的函数,称为闭包【内部函数是闭包】
function fn(){
var a = 10;
return function innerFn(){
console.log(++a);
}
}
var outFn = fn();
outFn();// 11
outFn();// 12
fn()();// 11
fn()();// 11
4-9. 预解析
预解析==变量提声
全局:
1. 首先将var 声明的变量只声明不赋值,值是undefined 2. 针对 function ,即声明同时赋值 3. 如果var 的变量和 function 函数名 同名,function权重高 4. 函数预解析 * 4-1. 声明式定义:声明并赋值 * 4-2. 字面量定义:只声明不赋值,值是undefined
局部[函数内的预解析]:
- 形参声明并赋值
- 同全局预解析机制
4-9-1. 全局预解析机制
4-9-2. 函数内部预解析
4-10.函数的分类
具名函数
匿名函数
自执行函数
- 模块化的雏形
4-11. arguments
arguments 是函数实参的集合,是一个伪数组,函数调用的时候,js解析器帮我们注入的,无需声明可以直接使用。
什么是伪数组?
- 有元素
- 元素有下标,下标从0开始
- 有长度length属性
- 但是不能使用数组中的方法
如何遍历伪数组?
使用下标和长度进行循环遍历
将伪数组转化为数组之后,使用数组的方法遍历
2-1.
Array.prototype.slice.call(arguments,0)
2-2.
Array.from(arguments)
2-3.
[...arguments]
4-12. 递归
什么是递归?在函数内部自己调用自己
什么时候应用递归:当前步骤没有办法得到具体的结果,只能深入递归直到结果产生
递归的应用:
- 对象的深拷贝 【手写代码经常出的题】
- vue-递归组件-无限级分类
arguments.callee
- 值就是当前函数本身
- 一般应用于递归调用
function jieCheng(num){
console.log(arguments.callee);// 当前函数本身,一般应用于递归调用
jieCheng = null;
// return num === 1 ? 1 : num * jieCheng(num - 1);
return num === 1 ? 1 : num * arguments.callee(num - 1);
}
console.log(jieCheng(5));