函数做为第一类对象
javascript中一个重要的概念:函数是第一类对象,或者称为一等公民。因为它具有对象的特性:
- 能以字面量的方式创建
- 能作为函数的参数传递
- 能动态的添加属性
- 可以赋值给任意变量,数组项和对象的属性
- 可以作为函数的返回值(闭包)
函数作为对象
动态存储回调函数
在某种需求中通过事件需要调用回调函数集合的场景,在我们像函数集合添加回调函数的时候需要保证回调函数的唯一性,可以利用函数对象的特性,添加唯一标示属性id。保证在每一次添加回调函数的时候先检查该回调函数是否已经添加。如果已经添加过,就不必要在添加相同的回调函数到集合中。
代码实现
class Test {
constructor() {
this.cache = []
this.nextId = 1
}
addFn(callback) {
if (!callback.id) {
callback.id = nextId++
this.cache.push(callback)
return true
}
return false
}
}
自记忆函数
自记忆函数简单来首就是在使函数拥有某种缓存方式,在调用函数的时候可以直接返回结果,类似记住某种操作之后就不会在执行一下的动作。在复杂的计算过程中,我们可以通过该中技术,把对于的计算复杂的结果储存起来,在下次调用的时候可以直接使用。
使用场景:动画中的计算,搜索不经常变化的数据或者是任何耗时的计算操作
需要主要几个点:
1 需要执行的操作基本上不会有太多变化
2 内存泄漏问题,如果不控制缓存属性的大小,可能导致添加过多属性导致内存泄漏。
3 不利于单元测试
在vue中的依赖收集中就用到函数属性存储数据技术。
Dep.target = null;
var targetStack = [];
function pushTarget (target) {
targetStack.push(target);
Dep.target = target;
}
// target 属性存储来当前的Watcer 实例
get: function reactiveGetter () {
var value = getter ? getter.call(obj) : val;
if (Dep.target) {
dep.depend();
if (childOb) {
childOb.dep.depend();
if (Array.isArray(value)) {
dependArray(value);
}
}
}
return value
}
Dep.prototype.depend = function depend () {
if (Dep.target) {
Dep.target.addDep(this);
}
};
函数的定义
1 函数定义和函数表达式
function name() {
}
(function (){}) // 函数表达式,可以不需要函数名
2 箭头函数(ES6新增项,和普通函数的区别在于)
- 箭头函数内部获取不到arguments对象
- this指向被定义时的上下文
- 函数构造函数
- 通过new关键字
const myFn = new Function('a', 'b', 'return a + b')
模版编译中常常会用到这种方式生成渲染函数
- 生成器函数
function* myFn() {}
其特点是该函数可以在执行中退出后能在次进去执行过程,而且还能保留函数内部的值。可以 与关键字yield控制执行流程,co库中就使用到这种技术,可以实现等待异步结束。
5 async函数
异步函数,主要是与关键字await使用,解决调之前promise的长链式调用,让代码可读性更高
网友评论