高阶函数
一个函数做为另一个函数的参数,或者返回值
作用:包装函数,装饰器
before
function makeCoffee(){
console.log('做咖啡')
}
Function.prototype.before = function(fn){
return ()=>{
fn();
this();
}
}
let newFn = makeCoffee.before(()=>{
console.log('加糖')
})
newFn();
// 输出:
// 加糖
// 做咖啡
React 事务
function affair(arr,fn){
return ()=>{
arr.forEach(v=>v.init())
fn();
arr.forEach(v=>v.end())
}
}
let newFn = affair([
{
init() {
console.log('init');
},
end() {
console.log('end');
},
},
{
init() {
console.log('init2');
},
end() {
console.log('end2');
},
},
], function () {
console.log('xxxx');
});
newFn();
/**
* 输出:
* init
*. init2
*. xxxx
*. end
*. end2
*/
函数柯粒化
将一个有多个参数的函数,分布执行
function add(a,b,c,d,e){
return a + b + c + d + e;
}
function curry(fn,lenArr = []){
return (...args)=>{
lenArr = [...lenArr,...args];
if(lenArr.length === fn.length){
return fn(...lenArr);
}else{
return curry(fn,lenArr);
}
}
}
let newFn = curry(add)(1)(2);
console.log(newFn); // [Function]
let r = newFn(3)(4)(5)
console.log(r); // 15
解决异步的方案: callback
const fs = require('fs')
const path = require('path')
function getData(name,callback){
fs.readFile(path.resolve(__dirname,name),function(err,data){
if(err){
console.log(err)
return;
}
callback(data)
})
}
getData('a.txt',(data)=>{
console.log(data)
})
闭包
一个函数不在当前作用域下执行
-
作用1:隐藏变量,避免全局污染
-
作用2:可以读取函数内部的变量
-
缺点:造成内存泄漏
解决异步并发问题
- 计数器
const fs = require('fs')
const path = require('path')
let obj = {};
fs.readFile(path.resolve(__dirname,'a.txt'),(err,data)=>{
if(err){
console.log(err)
return;
}
console.log(data.toString()) // aaaa
obj['a'] = data.toString();
allResolve();
})
fs.readFile(path.resolve(__dirname,'b.txt'),(err,data)=>{
if(err){
console.log(err)
return;
}
console.log(data.toString()) // bbbb
obj['b'] = data.toString();
allResolve();
})
function calcNum(){
let num = 2;
return ()=>{
if(--num === 0){
console.log(obj) // { a: 'aaaa', b: 'bbbb'}
}
}
}
let allResolve = calcNum();
- 发布订阅
const fs = require('fs')
const path = require('path')
let observe = {
arr: [],
on(fn){
this.arr.push(fn)
},
emit(){
this.arr.forEach(fn=>fn())
}
}
// 订阅
observe.on(function(){
console.log(obj);
})
let obj = {};
fs.readFile(path.resolve(__dirname,'a.txt'),(err,data)=>{
if(err){
console.log(err)
return;
}
console.log(data.toString()) // aaaa
obj['a'] = data.toString();
// 发布
observe.emit();
})
fs.readFile(path.resolve(__dirname,'b.txt'),(err,data)=>{
if(err){
console.log(err)
return;
}
console.log(data.toString()) // bbbb
obj['b'] = data.toString();
// 发布
observe.emit();
})
观察者模式
观察者模式与发布订阅的区别
- 观察者模式 包含 发布订阅模式; 除了发布订阅,里面还包含观察者和被观察者;
// 观察者
class Observer {
constructor(name){
this.name = name;
}
update(o){
console.log('状态更新了')
console.log(o.state)
}
}
// 被观察者
class Subject {
constructor(name){
this.name = name;
this.state = '开心'
this.arrFn = [];
}
setState(value){
this.state = value;
this.arrFn.forEach(v=>v.update(this))
}
attach(o){
this.arrFn.push(o)
}
}
let baobao = new Subject('baobao')
let mama = new Observer('mama')
let baba = new Observer('baba')
baobao.attach(mama) // 添加观察者
baobao.attach(baba) // 添加观察者
baobao.setState('不开心') //被观察者状态更新了,通知观察者