Function
什么是
函数其实是一个封装一段代码段的对象,函数名其实仅是引用函数对象的一个普通变量
何时
只要一项任务,可能被反复使用,都要定义为函数
创建
1. 声明:
function 函数名(参数列表){ 函数体; return 返回值}
注
:创建会被提前,在开始执行程序前引擎会首先查找var声明的变量和function声明的函数将其提前到当前作用域的顶部集中创建,赋值留在原地
解决:
- 所有变量和函数的声明都放在当前作用域的顶部`
- ES6 可用let代替var,要求当前作用域中let a之前不允许出现未声明的a
2. 直接量:
var 函数名 = function(参数列表){函数体;return 返回值}
注:不会被声明提前
3. New:
var 函数名 = new Function(“参数名1”,“参数名2”,…,“函数体;return 返回值”)
参数
1.接收函数执行时必须的数据的变量
2.可让函数更灵活
3.何时用参数:只要函数必须某些数据才能正常执行
返回值
1.函数的执行结果
2.何时:如果调用者需要获取函数的返回值
调用
让引擎按照函数的步骤清单,执行任务
强调:函数不调用不执行,只有调用才执行
重载
声明时: 相同函数名,不同参数列表的多个函数
调用时: 根据传入参数的不同,自动选择匹配的函数执行
为什么: 减少API的数量,减轻调用者的负担
何时:只有一项任务,需要根据不同的参数,执行不同的操作时
**问题:**js语法不支持重载,js不允许多个同名函数存在`
解决:
- 每一个函数内,都有一个arguments对象接住所有传入函数的参数值
- 根据arguments的元素内容或元素个数,判断执行不同的操作
arguments
- 函数调用时,自动创建的
- 自动接收所有传入函数的参数值的
- 类数组对象:
a. 长得像数组的对象
b. VS数组:
相同点:下标,length ,for/for of遍历
不同点:数组是Array类型,类数组是Object类型,无法使用数组API
匿名函数
什么是:函数创建时,没有指定函数名
为什么:节约内存,临时划分作用域,避免全局变量
何时:只有一个函数只有一次
1. 回调callback
将一个函数作为参数传入另一个函数内,被其他函数调用
arr.sort(function(a,b){return a-b}) //ES6 - arr.sort((a,b)=> a-b)
2.自调
定义函数后自己调用自己,调用后,立即释放
何时:定义一个临时作用域,减少使用全局变量,避免全局污染
如何
(function(参数列表) { 函数体; return 返回值 } (参数列表))
(function(参数列表) { 函数体; return 返回值}) (参数值列表)
函数作用域和作用域链
作用域(scope)
变量的可用范围,其实是一个对象
全局作用域对象
window: 保存全局变量
优点:可反复使用
缺点:随处可用,全局污染
函数作用域对象
AO: 保存局部变量
优点:仅函数内可用,不会被污染
缺点:不可重用
注:优先在函数作用域中找局部边变量使用,如果局部没有,才会去全局找,全局也没有时,才报错
函数的生命周期
开始执行程序前:
- 创建ECS:专门保存正在调用的函数的执行环境的数组
- 首先在ECS中添加浏览器主程序的执行环境main
- 创建全局作用域对象window,所有全局变量都是保存在window对象中
- main执行环境引用window
定义函数时
- 用函数名声明全局变量
- 创建函数对象,封装函数定义
- 函数对象的scope属性,指回调函数创建时的作用域
- 函数名变量引用函数对象
作用域链(scope chain)
- 由各级作用域逐级引用,形成的链式结构
- 保存着所有的变量
- 控制着变量的使用顺序
- 函数中,没有用任何对象/this就直接访问的变量,在作用域中找
闭包(closure)
什么是: 既重用变量,又保护变量不被污染的机制
何时: 既重用变量,又保护变量不被污染
如何:
- 外层函数:包裹受保护的变量和操作变量的内层函数
- 外层函数要返回内层函数的对象
a. return function(){…}
b. 直接给全局变量赋值一个内部function
c. 将内部函数保存在一个对象的属性或者数组元素中
return [function,function,function]
return {function(){...}}
- 调用外层函数,用外部变量借助返回的内层函数对象,形成闭包
闭包的形成
外层函数调用后,外层函数的作用域对象(AO),无法释放,被内层函数对象的scope引用着
缺点:容易造成内存泄漏
如何释放闭包:将引用内层函数对象的外部变量置为null,导致内层函数对象被释放,
导致外层函数的作用域(AO)被释放