DEV Community

Cover image for Handwritten implementation of call, apply, bind
Prototype chain
Prototype chain

Posted on

Handwritten implementation of call, apply, bind

preparation

First, define the show function to print the name attribute and parameters in the specified object;

function show(...args) {
    console.log(this.name);
    console.log(args);
}
Enter fullscreen mode Exit fullscreen mode

Define the object, which contains the name attribute

let obj = {
    name:'philip'
}
Enter fullscreen mode Exit fullscreen mode

Define function, convenient to call

    function mycall(fn, object, ...args) {
        return fn._call(object, ...args)
    }

    function myapply(fn, object, array) {
        return fn._apply(object, array)
    }

    function mybind(fn , object , ...args){
        return fn._bind(object,...args)
    }
Enter fullscreen mode Exit fullscreen mode

call

As a prototype property of a function, it needs to be mounted on the function prototype
The first parameter is the object, and the second parameter is any number of parameters

Function.prototype._call = function (obj,...args) {

}
Enter fullscreen mode Exit fullscreen mode

Add attributes to the object. The type is the function that currently uses the call method
Call the function, delete the function attribute after calling to make space

Function.prototype._call = function (obj,...args) {
    obj.fn = this // Add attributes to the object. The type is the function that currently uses the call method
    obj.fn(...args) // Call the function
    delete obj.fn // delete the function attribute after calling to make space
}
Enter fullscreen mode Exit fullscreen mode

apply

It has the same function as the call method, but the second parameter needs to be an array

Function.prototype._apply = function (obj,args=[]) {
    if(args && !(args instanceof Array)){
        throw new Error("TypeError:apply only receive array")
    }
    obj.fn = this
    obj.fn(...args)
    delete obj.fn
}
Enter fullscreen mode Exit fullscreen mode

bind

The bind method returns a function that can receive any parameter

Function.prototype._bind = function (obj, ...args1) {
        return (...args2) => {
            obj.fn = this
            obj.fn(...args1.concat(...args2))
            delete obj.fn
        }
    }
Enter fullscreen mode Exit fullscreen mode

test

mycall(show, obj, 'a', 'b', 'c') // philip ['a','b','c']
myapply(show, obj, ['a', 'b', 'c']) // philip ['a','b','c']
let result = mybind(show,obj,'a', 'b');result('c')// philip ['a','b','c']
Enter fullscreen mode Exit fullscreen mode

Top comments (0)