函数(Function)
js内的一个引用数据类型
函数的参数
- 形参
- 书写在函数定义阶段的 () 中
- 可以给形参默认值,如果没有传递实参就使用默认值
- 实参
- 书写在函数调用阶段的 () 中
- 按照顺序, 依次给每一个形参赋值
函数两阶段
- 函数定义阶段
- 函数调用阶段
函数定义阶段
- 声明式函数: function fn() {}
- function 定义函数的关键字
- fn 函数名(也是一个变量名)
- () 书写形参
- {} 函数体
- 赋值式函数: var n =function () {}
函数调用阶段
- 声明式函数可以先调用或者后调用
- 赋值式函数必须声明以后调用
函数两阶段大概流程
函数定义阶段
- 在 堆内存 中开辟一段函数存储空间
- 存储函数体代码, 此时并不解析变量
- 把函数 空间地址 赋值给 栈内存 中的变量
函数调用阶段
- 按照变量名存储的地址找到该函数存储空间(1. 判断变量名是否存在, 2. 判断该变量存储的地址是否是一个函数空间)
- 在调用栈内开辟一段新的 函数执行空间
- 在开辟的新空间内进行 1. 形参赋值 2. 预解析 3. 把代码从上到下执行
- 执行完毕, 把开辟的执行空间销毁
认识预解析
在代码执行之前, 对代码进行通读并解释
预解析阶段: 重复的声明没有意义, 重复的赋值有意义
- 函数预解析: 当你调用函数时, 对函数体内的代码进行预解析, 解析完毕执行代码
- 全局预解析: 打开浏览器时, 进行预解析, 但是不解析函数体内的代码, 然后执行代码
预解析干了什么?
- 对 var 关键字定义的变量进行解析
- 告诉浏览器, 定义了一个变量, 但是暂时不赋值
- 对 声明式函数 进行预解析
- 告诉浏览器, 定义了一个变量(函数名), 并且赋值为一个函数
认识作用域
指一个变量(函数), 可以使用生效的范围
作用域分类
- 全局作用域: 一个 html 页面就是一个全局作用域(Window)
- 私有作用域(函数作用域): 只有函数生成私有作用域
作用域提供了三个机制
变量定义机制
- 定义在哪一个作用域内的变量, 就是哪一个作用域的私有变量
- 只能在该作用域和后代作用域使用, 不能在父级作用域使用
变量访问机制
- 获取一个变量的值时, 首先在本作用域查找, 如果没有,依次往父级作用域查找
- 直到全局作用域没有, 报错
变量赋值机制
- 给一个变量赋值时, 首先在本作用于查找, 如果没有, 依次往父级作用域查找
- 直到全局作用域没有, 把该变量定义为全局变量再进行赋值