JS手写函数实现

245 阅读2分钟

1,实现函数sum,按照下面要求

sum()===0;
sum(1)() ===1;
sum(1)(2)() ===1+2;
sum(1)(2)(3)() === 1+2+3;
** ......以此类推 **

 function sum(num) {
      const arr = []
      if (!num) {
          return 0
      }
      arr.push(num)
      return function fn(num1) {
          if (!num1) {
              return arr.reduce((p, n) => p + n)
          }
          arr.push(num1)
          return function (num2) {
              return fn(num2)
          }
      }
  }
  console.log(sum(1)(2)(3)(4)(5)())

2,实现函数isInt 判断输入值是否为整数

isInt(1)===true;
isInt(NaN)===false;
isInt(Infinity)===false;
isInt('')===false;
** ......以此类推 **

  function isInt(num) {
  	  // 不是number类型 || 是Infinity、-Infinity || 是NaN 返回 false
      if (typeof num !== 'number' || !isFinite(num) || isNaN(num)) return false
      return Math.floor(num) === num
  }

3,实现函数type能够精准判断当前传入数据类型

type(1)==='Number';
type({})==='Object';
type([])==='Array';
type(null)==='Null';
** ......以此类推 **

 function type(value) {
        const str = Object.prototype.toString.call(value)
        return str.slice(8).replace(/]/, '')
    }

4,实现函数getKeyOfObject, 获取多级嵌套的对象的key值

var obj = {
    a: '12',
    b: '23',
    first: {
        c: 34,
        d: 45,
        second: {
            3: 56,
            f: 67,
            three: {
                g: '78',
                h: '89',
                i: '90'
            }
        }
    }
}
getKeyOfObject(obj) === ["a", "b", "c", "d", "3", "f", "g", "h", "i"]
  // 判断当前传入数据类型
  function type(value) {
      const str = Object.prototype.toString.call(value)
      return str.slice(8).replace(/]/, '')
  }
  // 获取多级嵌套的对象的key值
  function getKeyOfObject(obj, keys = []) {
      for (let key in obj) {
          if (type(obj[key]) === 'Object') {
              getKeyOfObject(obj[key], keys)
          } else {
              keys.push(key)
          }
      }
      return keys
  }

5,实现函数getDiffMonth 输入两个日期字符串返回他们中间的月份

输入:'2018-10' '2019-1'
返回:['2018-11', '2018-12']

 function getDiffMonth(date1, date2) {
            const res = []
            date1 = new Date(date1)
            date2 = new Date(date2)
            if (date2 === date2) return []
            //  start:开始时间, end:结束时间
            let start, end
            date1 > date2 && (start = date2, end = date1)
            date1 < date2 && (start = date1, end = date2)
            // 如果同年 计算中间月份 
            if (start.getFullYear() === end.getFullYear()) {
                let diff = end.getMonth() - start.getMonth()
                if (diff === 0) return []
                for (let i = 1; i < diff; i++) {
                    res.push(start.getFullYear() + '-' + (parseInt(start.getMonth()) + 1 + i))
                }
                return res
            } else {
                // 如果不同年 计算起始时间到12月月份
                let startMonth = start.getMonth() + 1
                while (startMonth !== 12) {
                    res.push(start.getFullYear() + '-' + (startMonth + 1))
                    startMonth++
                }
                // 如果不同年 计算中间年的月份 比如2020-2022 中间年月份就是 2021年12个月
                let diffYear = end.getFullYear() - start.getFullYear()
                if (diffYear > 1) {
                    for (let i = 1; i < diffYear; i++) {
                        for (let j = 1; j < 13; j++) {
                            console.log('1233');
                            res.push((start.getFullYear() + i) + '-' + j)
                        }
                    }
                }
                // 如果不同年 计算结束年从一月到结束月份
                let lastMonth = parseInt(end.getMonth())
                let tempMonth = 0
                while (tempMonth !== lastMonth) {
                    res.push(end.getFullYear() + '-' + (tempMonth + 1))
                    tempMonth++
                }
                return res
            }
        }

6,实现函数deepCopy,实现深拷贝,对输入值返回深拷贝后的值.

        function deepCopy(value) {
            const baseType = ['number', 'boolean', 'string', 'undefined']
            function copy(value, resul) {
                // 基本类型以及函数直接赋值 (此处不考虑函数类型深拷贝) 否则进行 // 进行深拷贝
                if (baseType.includes(typeof (value)) || value === null || value instanceof Function) {
                    return resul = value
                } else if (value instanceof Array || value instanceof Object) {

                    for (let key in value) {
                        if (!resul) {
                            resul = value instanceof Array ? [] : {}
                        }
                        if (value[key] instanceof Object && !(value[key] instanceof Function)) {
                            resul[key] = value[key] instanceof Array ? [] : {}
                            copy(value[key], resul[key])
                        } else {
                            resul[key] = value[key]
                        }
                    }
                }
                return resul
            }
            return copy(value)
        }
        
        
        let obj = [1, '', undefined, null, false, { a: 1, b: [1, 2, 3], c: { d: [1, 2, 3] } }, [1, 2, 3], _ => { }]
        let deepObj = deepCopy(obj)
        console.log(obj, deepObj);

7,实现函数myFlat

输入:[1, 2, 3, [4, 5, 6, [7, 8, 10, 9]]]
返回:[1, 2, 3, 4, 5, 6, 7, 8, 10, 9]

 function myFlat(arr) {
    const res = []
    function flat(arr, res) {
        for (let key in arr) {
            if (arr[key] instanceof Array) {
                flat(arr[key], res)
            } else {
                res.push(arr[key])
            }
        }
        return res
    }
    return flat(arr, res)
}
let arr = [1, 2, 3, [4, 5, 6, [7, 8, 10, 9]]]
console.log(myFlat(arr));

8,实现Promise版本ajax(get,post)

 function ajax_p({ url = '', params = {}, method = 'get' }) {
            // 构建XMLHttpRequest 
            const xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject()
            // 判断请求方式
            method = method.toLowerCase()
            if (method === 'get') {
                // get方式需要将对象参数组装成?a=1&b=2...
                let urlStr = Object.keys(params).reduce((p, n) => p + n + '=' + params[n] + '&', url + '?')
                urlStr = urlStr.slice(0, urlStr.length - 1)
                xhr.open(method, urlStr)
                xhr.send();
            } else if (method === 'post') {
                xhr.open(method, url)
                xhr.setRequestHeader('contentType', 'application/x-www-form-urlncoded')
                xhr.send(params);
            }
            // 监听返回数据 保存到promise
            return new Promise((resolve, reject) => {
                xhr.onreadystatechange = function () {
                    if (xhr.status === 200 && xhr.readyState === 4) {
                        resolve(xhr.responseText)
                    } else if (xhr.status !== 200 && xhr.readyState === 4) {
                        reject('error')
                    }
                }
            })
        }

9,写一个函数,可以控制最大并发数

 function control_(arr, max = 2) {
            const arrTemp = arr.splice(0, 2)
            function run(arrTemp_) {
                arrTemp_.forEach((fn, i) => {
                    if (fn.r) return
                    fn.r = 1 // 挂个标志 
                    fn().then(e => {
                        console.log('e:', e);
                    }).catch(err => {
                        console.log('err:', err);
                    }).finally(_ => {
                        if (arr.length) {
                            delete fn.r
                            // 任务队列事情做完了 删掉 腾出位置给其他人  // 加入下一个任务
                            arrTemp_[i] = arr.shift()
                            // 递归继续执行
                            run(arrTemp_)
                        }

                    })
                })
            }
            run(arrTemp)
        }
        // Promise生成器
        function createP(n) {
            let res = []
            for (let i = 0; i < n; i++) {
                res.push(function () {
                    return new Promise(resolve => { let t = Math.floor(Math.random() * 10); setTimeout(() => { resolve(t) }, 1000 * t) })
                })
            }
            return res
        }
        control_(createP(5))

1075