SOURCE

// 节流
const throttle = (fn, delplay) => {
    let timer = null
    return function (...args) {
        const ctx = this
        if (timer) {
            return
        }
        timer = setTimeout(() => {
            fn.apply(ctx, args)
            timer = null
        }, delplay)
    }
}

// 防抖
const debounce = (fn, delplay) => {
    let timer = null
    return function (...args) {
        const ctx = this
        if (timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(() => {
            fn.apply(ctx, args)
        }, delplay)
    }
}

// new操作符
const create = (Con, ...args) => {
    let obj = {}
    Object.setPrototypeOf(obj, Con.prototype)
    const res = Con.apply(obj, args)
    return typeof res === 'Object' ? res : obj
}

// 深拷贝
const deepClone = (source) => {
    let res = Array.isArray(source) ? [] : {}
    for (let i in source) {
        const item = source[i]
        if (typeof item === 'object') {
            res[i] = Array.isArray(item) ? [] : {}
            res[i] = deepClone(item)
        } else {
            res[i] = item
        }
    }
    return res
}

// promise
class MyPromise {
    constructor(fn) {
        this.state = 'pending'
        this.successRes = null
        this.rejectRes = null
        this.successArr = []
        this.rejectArr = []
        fn(this.resolve, this.reject)
    }
    resolve = (val) => {
        if (this.state === 'pending') {
            this.state = 'success'
            this.successRes = val
            this.successArr.forEach(callback => callback())
        }
    }
    reject = (val) => {
        if (this.state === 'pending') {
            this.state = 'fail'
            this.rejectRes = val
            this.rejectArr.forEach(callback => callback())
        }
    }
    then = (onSuccess, onFail) => {
        if (this.state === 'pending') {
            this.successArr.push(onSuccess)
            this.rejectArr.push(onFail)
        }
        if (this.state === 'success') {
            onSuccess(this.successRes)
        }
        if (this.state === 'fail') {
            onFail(this.rejectRes)
        }
    }
}

// promise.all
Promise.prototype.myAll = function (promises) {
    promises = Array.from(promises)
    let res = []
    let count = 0
    return new Promise((resolve, reject) => {
        for (i in promises) {
            const pro = Promise.resolve(promises[i])
            pro.then(val => {
                res[i] = val
                if (++count === promises.length) {
                    resolve(res)
                }
            }, err => {
                reject(err)
            })
        }
    })
}

// bind
Function.prototype.myBind = function (con, ...args) {
    con = con || window
    con.fn = this
    return function (..._args) {
        _args = args.concat(_args)
        con.fn(_args)
        delete con.fn
    }
}

// apply
Function.prototype.myApply = function (con, args = []) {
    con = con || window
    con.fn = this
    con.fn(...args)
    delete con.fn
}

// call
Function.prototype.myCall = function (con, ...args) {
    con = con || window
    con.fn = this
    con.fn(...args)
    delete con.fn
}

// compose
const compose = (...args) => {
    let fn1 = args[0]
    let res = null
    return function (..._args) {
        res = fn1(..._args)
        for (let i = 1; i < args.length; i++) {
            const fn = args[i]
            res = fn(res)
        }
        return res
    }
}

const compose2 = (...funcs) => {
    if(funcs.length === 0){
        return args => args
    }
    if(funcs.length === 1){
        return funcs[0]
    }
    return funcs.reduce((acc, curr) => {
        return (...args) => curr(acc(...args))
    })
}

let sayHello = (...str) => `Hello , ${str.join(" And ")}`;
let toUpper = str => str.toUpperCase();
let combin = compose(
  sayHello,
  toUpper
);
// console.log(combin("jack", "bob")); // HELLO , JACK AND BOB

// reduce
Array.prototype.myReduce = function (fn, intVal) {
    const array = this
    let acc = intVal || array[0]
    let start = intVal ? 0 : 1
    for (let i = start; i < array.length; i++) {
        acc = fn(acc, array[i], i, array)
    }
    return acc
}

// add(1)(2)(3) add(1, 2)(3)
const curry = (fn, ...args) => {
    if (args.length >= fn.length) {
        return fn(...args)
    }
    return function (..._args) {
        return curry(fn, ...args, ..._args)
    }
}
const sum = (x, y, z) => {
    return x + y + z
}
const add = curry(sum)

// add(1)(2)(3)...add(n)
const addX = (x) => {
    let fn = function (y) {
        return add(x + y)
    }
    fn.toString = function () {
        return x
    }
    return fn
}

// 算法相关
// 快速排序
const quickStart = (arr = []) => {
    if (arr.length <= 1) {
        return arr
    }
    let mid = Math.floor(arr.length / 2)
    let left = [], right = [], curr = arr.splice(mid, 1)[0]
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] <= curr) {
            left.push(arr[i])
        } else {
            right.push(arr[i])
        }
    }
    return quickStart(left).concat([curr], quickStart(right))
}
// console.log(quickStart([4, 5, 1, 7, 7, 8, 8, 3, 3, 0]))

// 三数之和
const threeSum1 = (arr, target) => {
    let res = []
    for (let i = 0; i < arr.length; i++) {
        for (let j = i + 1; j < arr.length - 1; j++) {
            for (let k = j + 1; k < arr.length - 2; k++) {
                if (arr[i] + arr[j] + arr[k] === target) {
                    res = [i, j, k]
                }
            }
        }
    }
    return res
}

const threeSum2 = (arr, target) => {
    let res = []
    arr = arr.sort((a, b) => a - b)
    for(let k = 0; k < arr.length; k++){
        let i = k + 1
        let j = arr.length - 1
        let first = arr[k]
        if(first >= 12){
            continue
        }
        while(i < j){
            let second = arr[i]
            let last = arr[j]
            let sum = first + second + last
            if(sum === target){
                res.push([k, i, j])
                i++
                j--
            } else if(sum > target){
                j--
            }else {
                i++
            }
        }
    }
    console.log(res)
}

threeSum2([12, 1, 2, 3, 4, 5, 6, 24, 34, 45], 12)
console 命令行工具 X clear

                    
>
console