SOURCE

const log = console.info
const data = [{ key: 'a', value: '11' }, { key: 'b', value: '22' }, { key: 'c', value: '33' }]
let process = data => data.reduce((pre, cur) => ({ ...pre, [cur.key]: cur.value }), {})
log(process(data))

const obj1 = { name: 'dog', info: { age: 3 }, fn: function () { }, arr: [1] }
let deepClone = data => {
    if (data == null) return data
    let target = Array.isArray(data) ? [] : {}
    for (const k in data) {
        if (typeof data[k] === 'object') {
            target[k] = deepClone(data[k])
        } else if (typeof data[k] === 'function') {
            target[k] = new Function(`return ${data[k].toString()}`)
        } else {
            target[k] = data[k]
        }
    }
    return target
}
log(deepClone(obj1).fn === obj1.fn)
log(JSON.parse(JSON.stringify(obj1)))

//原型链覆盖
let arr = [1, 2]
Array.prototype[Symbol.iterator] = function () {
    var self = this
    return {
        next() {
            if (self.length) {
                return { value: self.pop(), done: false }
            }
            return { done: true }
        }
    }
}
// for (i of arr) {
//     console.log(i)
// }

const debounce = (fn, delay = 200) => {
    let timer;
    return function (...args) {
        if (timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(() => fn.call(this, ...args), delay)
    }
}
// let temp = debounce(() => log('a'))
// temp()
// temp()
// temp()

const throttling = (fn, delay = 200) => {
    let timer;
    return function (...args) {
        if (timer) {
            return
        }
        timer = setTimeout(() => fn.call(this, ...args), delay)
    }
}

// let temp = debounce(() => log('a'),1000)
// temp()
// setTimeout(() => temp(), 100)
// setTimeout(() => temp(), 1200)

var object = { 'a': [{ 'b': { 'c': 3 } }] };
const _get = (obj, path) => {
    let newPath = []
    if (Array.isArray(path)) {
        newPath = path
    } else {
        newPath = path.replace(/\[/g, '.').replace(/\]/g, '').split('.')
    }
    return newPath.reduce((tol, cur) => {
        return (tol || {})[cur]
    }, obj) || obj
}

log(_get(object, 'a[0].b.c'))
// => 3
log(_get(object, ['a', '0', 'b', 'c']))
// => 3
log(_get(object, 'a.b.c', 'default'))
// => 'default'

class EventBus {
    constructor() {
        this.events = {}
    }
    on(event, cb) {
        if (!this.events[event]) this.events[event] = []
        this.events[event].push(cb)
    }
    off(event, cb) {
        if (!cb) {
            return this.events[event] = []
        }
        this.events[event] = this.events[event].filter(cb=>cb!==cb)
    }
    emit(event, ...val) {
        const cbs = this.events[event]
        if (cbs) {
            cbs.forEach(cb => cb.call(this, ...val))
        }
    }
    once(event, cb) {
        const fun = (...val)=>{
            cb.call(this,...val)
            this.off(event,fun)
        }
        this.on(event, fun)
    }
}

let e = new EventBus()
e.on('one', log)
e.on('two', log)
e.once('three', log)
e.emit('one', 1)
e.off('one', 1)
e.emit('one', 1)
e.emit('two', 2)
e.off('two')
e.emit('two', 2)

e.emit('three', 3)
e.emit('three', 3)

class Storage{

}
class Interface {

}
class A implements Interface 

}
console 命令行工具 X clear

                    
>
console