The profile

The purpose of this article is to simulate the implementation of utility functions such as Call, apply, bind, map, Fiter, and so on that are either natively provided in the Javascript language or packaged in some libraries

Implementing the Call method

// The key to implementing the Call and apply methods is to pass the method itself as an attribute to the specified this and call the method itself manually on the specified this
Function.prototype.call2 = function(arg, ... args) {
    const context = arg || window

    context._fn_call = this

    constresult = context._fn_call(... args)delete context._fn_call

    return result
}
Copy the code

Simulate the implementation of the Apply method

// The key to implementing the Call and apply methods is to pass the methods themselves as attributes to the specified
Function.prototype.apply2 = function(arg, args = []) {
    const context = arg || window

    context._fn_apply = this

    constresult = context._fn_apply(... args)delete context._fn_apply

    return result
}
Copy the code

Implement bind

Function.prototype.bind2 = function (arg, ... args) {
    const context = arg || window

    context._fn_bind = this

    return function (. argsInner) {
        constresult = context._fn_bind(... args.concat(argsInner))delete context._fn_apply

        return result
    }
}
Copy the code

Implementing the Map method

Array.prototype.map2 = function (fn) {
    const result = []

    for (let item of this) {
        result.push(fn(item))
    }

    return result
}

const arr = [1.2.3.4]
console.log(arr.map2(v= > v * 2))
/ /,4,6,8 [2]
Copy the code

The simulation implements the Filter method

Array.prototype.filter2 = function (fn) {
    const result = []

    for (let item of this) {
        if (fn(item)) {
            result.push(item)
        } 
    }

    return result
}

console.log(arr.filter2(item= > item % 2= = =0))
/ / (2, 4]
Copy the code

Implement the once function

In some scenarios, when you want a function to be executed only once, you can use the following functions

function once (fn) {
    let flag = false

    return function (. args) {
        if(! flag) { flag =true
            returnfn(... args) }return}}function log () {
    console.log('foo')}const foo = once(log)

foo()
foo()
foo()
// foo, foo will only print once
Copy the code

Implements the Debounce anti-shock function

// This function takes a third argument to control whether the fn function is executed immediately
function debounce(fn, time, immediate) {
    let timeout, result

    const debounced = function() {
        const args = arguments
        const that = this

        if (timeout) clearTimeout(timeout)

        if (immediate) {
            constcallnow = ! timeout timeout =setTimeout(function() {
                timeout = null
            }, time)
            if (callnow) result = fn.apply(that, args)
        } else {
            timeout = setTimeout(function() {
                result = fn.apply(that, args)
            }, time)
        }

        return result
    }

    debounced.cancel = function() {
        clearTimeout(timeout)
        timeout = null
    }

    return debounced
}
Copy the code

Implement throttling function

How the throttling function works: Even if you keep firing events through operations, only execute events once in a while

function throttle(fn, wait) {
    let previos = 0
    let result

    return function() {
        const now = +new Date(a)if (now - wait > previos) {
            result = fn.apply(this.arguments)
            previos = now

            return result
        }
    }
}
Copy the code

Implements a shallow copy function of an object

function copy(obj) {
    if (typeofobj ! = ='object') return

    const newObj = obj instanceof Array ? [] : {}
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = obj[key]
        }
    }

    return newObj
}
Copy the code

Implements the deep-copy function of an object

function copy(obj) {
    if (typeofobj ! = ='object') return

    const newObj = obj instanceof Array ? [] : {}
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = typeof obj[key] === 'object' ? copy(obj[key]) : obj[key]
        }
    }

    return newObj
}
Copy the code

Implement multidimensional array flattening

Note: Multiple deep copies of an array cost performance. This function is designed to modify the original array directly

const arr = [1[2[3.4]]];

function flatten(arr) {
    while (arr.some(item= > Array.isArray(item))) { arr = [].concat(... arr) }return arr
}

console.log(flatten(arr))
// [1, 2, 3, 4]
Copy the code