概念
我们听起来很高大上,其实不然(他就是现在流行的伪精致,哈哈)
1. 如果一个函数的参数是另外一个函数那么就是一个高阶函数(很好理解)
2. 如果一个函数内部返回一个函数那么也是一个高阶函数
那么我们来自己在类上开发一个检测数据类型的方法,说起检测数据类型,那么我们就提一提几种检测数据类型的特点:
typeof
用法:typeOf xxx
缺点:用来检测数组,对象,正则,打印的都是 object
instanceof
用法:'1' instanceof String,[1] instanceof Array
缺点:是用来检测是否是一个类的实例,并不能检测基本数据类型,对于数组,函数,正则的__proto__最终指向的都是 Object 基类,所以 console.log(数组 / 函数 / 正则 instanceof Object)的结果都是 true, 并不是严格的检测
constructor
constructor 相对于 instanceof 可以准确地判断某个引用类型具体属于哪个类如 console.log([].constructor == Object)//false, 还可以检测基本数据类型
用法:console.log([].constructor == Array);
缺点:1.null 和 undegfined 没有 constructor,控制台会报错
2.constructor 检测数据类型不稳定,因为累的原型可以被重写,比如:function Fn(){}
Fn.prototype = new Array()
var f = new Fn
console.log(f.constructor)//Array
Object.prototype.toString.call()
这个方法是最精确最常用的,` 注意:这里的 toString 是对象上的 toString,(['1'].toString 这是 Array 原型上的 toString 不要搞混)`
console.log(Object.prototype.toString.call('s'))//[object String]第一项是写死的,第二项是检测这个实例指向的所属类型
好,现在理清了四种检测类型的优势和弊端,那么让我们封装一个让我们用起来更方便的高阶函数,执行 istype 就能返回 true 或 false
function isType(type){return function (content) {return Object.prototype.toString.call(content)==`[object ${type}]`
}
}
let isString=isType('String')
let isNumber=isType('Number')
console.log(isString('hello'));
console.log(isNumber(111));
上面使用了我们第二种概念 如果一个函数内部返回一个函数那么也是一个高阶函数
这种方式也叫闭包。那么我们在来看看闭包是什么?
闭包:一个函数不在自己所在的作用域下执行
闭包的优点:1. 使用闭包会形成不销毁的作用域。2. 保护私有变量不会被全局污染。
作用域销毁
说到作用域的销毁,那么我们来看一下不同的作用域不同的销毁方式:
1. 堆内存释放:当一个引用空间不被变量所占用浏览器会在空闲的时候释放
2. 栈内存释放
全局作用域:当关闭浏览器时会释放
私有作用域:不销毁:当一个私有作用域返回一个地址所被外界占用,此时这个作用域不会被销毁
销毁:一个作用域没有被外界占用,此时就销毁了
利用高阶函数实现两个异步函数执行完毕获取返回值
现在有这么一个需求,有一个对象let reLoadData={}
, 我想获取两个异步请求的结果作为 reLoadData 中的 key,value;
如果这样写的话读取文件时异步,异步就是执行后的返回结果不能立马获取,等待同步代码执行后才能获取最终结果; 所以在【2】的最后一行是获取不到的,比如【1】的列子就永远打印不出‘2’,因为他在等前面的 while 循环执行完毕,如果使用嵌套获取的话那么获取 reLoadData 的时间会加长,嵌套多了会形成回调地狱(恶魔金字塔)【1】while (true){}
setTimeout(()=>{console.log('2');
},500)【2】let fs = require('fs')
let reLoadData={}
fs.readFile('./name.txt','utf-8',(err,data)=>{console.log(data);
reLoadData.name=data
})
fs.readFile('./age.txt','utf-8',(err,data)=>{console.log(data);
reLoadData.age=data
})
console.log(reLoadData);
那么我们就利用高阶函数实现以下这个需求吧
let fs = require('fs')
fs.readFile('./name.txt','utf-8',(err,data)=>{out('name',data)
})
fs.readFile('./age.txt','utf-8',(err,data)=>{out('age',data)
})
function count(times,callback){let reLoadData={}
return function (key,value) {reLoadData[key]=value
if(--times==0){callback(reLoadData)
}
}
}
let out =count (2,function (reLoadData) {console.log(reLoadData)
})