高阶函数

概念

我们听起来很高大上,其实不然(他就是现在流行的伪精致,哈哈)

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)
})

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理