Рукописный код для внешнего письменного теста (1)

JavaScript

1. Сведение вложенных массивов/плоская реализация

описывать: расширяет многоуровневый вложенный массив в массив только с одним уровнем.

let array = [1, [1, 2, 3], [1, [2, {}]] ]
handle(array) // [1, 1, 2, 3, 1, 2, {}]

метод первый:

const handle = array => JSON.parse(`[${JSON.stringify(array).replace(/\[|]/g,'')}]`)
handle(array)   // [ 1, 1, 2, 3, 1, 2, {} ]

Точка знаний:JSON.parse()/JSON.stringify(),String.prototype.replace()

Способ второй:

const handle = array => array.reduce((accumulator, currentValue) => accumulator.concat(Array.isArray(currentValue) ? handle(currentValue): currentValue), [])
handle(array)   // [ 1, 1, 2, 3, 1, 2, {} ]

Точка знаний:Array.prototype.reduce(),Array.prototype.concat()

Способ третий:

const handle = array => {
    while(array.some(item => Array.isArray(item))) {
        array = [].concat(...array)
    }
    return array
}
handle(array)   // [ 1, 1, 2, 3, 1, 2, {} ]

Точка знаний:while,Array.prototype.some(),剩余参数

другие методы: ......

2. Дедупликация массива

описывать: Отфильтруйте повторяющиеся элементы в массиве.

let array = [1, 2, 1, '3', '3', 0 , 1]
handle(array)   // [1, 2, '3', 0]

метод первый:

const handle = array => [...new Set(array)]
handle(array)   // [ 1, 2, '3', 0 ]

Очки знаний:Set

Способ второй:

const handle = array => array.reduce((accumulator, currentValue) => {
    !accumulator.includes(currentValue) && accumulator.push(currentValue)
    return accumulator
}, [])
handle(array)   // [ 1, 2, '3', 0 ]

Очки знаний:Array.prototype.includes()

Способ третий:

const handle = array => {
    let map = new Map()
    return array.filter(item => map.has(item) ? false : map.set(item))
}
handle(array)   // [ 1, 2, '3', 0 ]

Точка знаний:Map,Array.prototype.filter()

другие методы: ......

3. Моделирование реализации вызова

    Function.prototype.Call = function(){
        let args = Array.from(arguments), context = args.shift()
        context = Object(context)
        context.fn = this
        let result = context.fn(...args)
        return (delete context.fn) && result
    };

4. Смоделируйте реализацию привязки

Function.prototype.bind = function () {
    let self = this, args = Array.from(arguments), context = args.shift();
    return function () {
        return self.apply(context, args.concat(...arguments))
    }
}

Точка знаний:apply、call、bind

5. Смоделируйте новую реализацию

const handle = function() {
    let fn = Array.prototype.shift.call(arguments)
    let obj = Object.create(fn.prototype)
    let o = fn.apply(obj, arguments)
    return typeof o === 'object' ? o : obj
}

Точка знаний:Object.create()

6. Формат чисел

const num = 123456789;
const handle = num => String(num).replace(/\B(?=(\d{3})+(?!\d))/g, ',')
handle(num) // 123,456,789

Точка знаний:正则表达式,String.prototype.replace()

7. Палиндромное суждение

const num = 123456654321;
const str = 'abababababab';
const handle = params => {
    let str_1 = String(params).replace(/[^0-9A-Za-z]/g, '').toLowerCase()
    let str_2 = str_1.split('').reverse().join()
    return str_1 === str_2 ? true : false
}
handle(num) // true
handle(str) // false

Точка знаний:String.prototype.split(),Array.prototype.join()

8. Дросселирование функций

таймер

const handle = (fn, interval) => {
    let timeId = null;
    return function() {
        if (!timeId) {
            timeId = setTimeout(() => {
                fn.apply(this, arguments)
                timeId = null
            }, interval)
        }
    }
}

Точка знаний:window.setTimeout

отметка времени

const handle = (fn, interval) => {
    let lastTime = 0
    return function () {
        let now = Date.now();
        if (now - lastTime > interval) {
            fn.apply(this, arguments)
            lastTime = now
        }
    }
}

9. Функция защиты от сотрясений

const handle = (fn, delay) => {
    let timeId
    return function() {
        if (timeId) clearTimeout(timeId)
        timeId = setTimeout(() => {
            fn.apply(this, arguments)
        }, delay)
    }
}

Отличие функции троттлинг от функции антивстряски: Функцию throttling и функцию anti-shake легко спутать.Для функции throttling кто-то часто стучит в дверь, но швейцар решает, открывать дверь или нет, в соответствии с фиксированным временем. Для функции защиты от сотрясений кто-то снаружи часто стучит в дверь, а швейцар решает, открывать дверь или нет, в зависимости от последнего стука в дверь.

Точка знаний:window.clearTimeout

10. Глубокое копирование

    const handle = function deepClone(params) {
        if (Array.isArray(params)) {
            return params.reduce((accumulator, currentValue) => {
                (typeof currentValue === 'object') ? accumulator.push(deepClone(currentValue)) : accumulator.push(currentValue)
                return accumulator
            }, [])
        } else {
            return Reflect.ownKeys(params).reduce((accumulator, currentValue) => {
                (typeof params[currentValue] === 'object') ? accumulator[currentValue] = deepClone(params[currentValue]) : accumulator[currentValue] = params[currentValue]
                return accumulator
            }, {})
        }
    }

11. Модель публикации-подписки

class Pubsub {
    constructor() {
        this.handles = {}
    }
    subscribe(type, handle) {
        if (!this.handles[type]) {
            this.handles[type] = []
        }
        this.handles[type].push(handle)
    }
    unsubscribe(type, handle) {
        let pos = this.handles[type].indexOf(handle)
        if (!handle) {
            this.handles.length = 0
        } else {
            ~pos && this.handles[type].splice(pos, 1)
        }
    }
    publish() {
        let type = Array.prototype.shift.call(arguments)
        this.handles[type].forEach(handle => {
            handle.apply(this, arguments)
        })
    }
}

const pub = new Pubsub()
pub.subscribe('a', function() {console.log('a', ...arguments)})
pub.publish('a', 1, 2, 3)
// a 1 2 3