Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

preface

Today’s handwritten series is also a note in my review process that helps me better understand and master the underlying logic of the Call, apply, and bind functions. Without further ado, let’s begin.

Write a call

According to MDN’s definition of call, the call() method calls a function with a specified this value and one or more arguments given separately. Take a simple chestnut.

/ / Function. The prototype. The call () sample
function fun(arg1, arg2) {
  console.log(this.name)
  console.log(arg1 + arg2)
}
const obj = { name: 'Mr. Chen?' }
// Accept a list of arguments; Method executed immediately
fun.call(obj, 1.2)

// Output: xiao Chen 3
Copy the code

To implement myCall, consider that if the first argument is null or undefined, the object will be converted to window.

Function.prototype.myCall = function(context) {
    if (typeof context === "undefined" || context === null) {
        context = window
    }
   / / the context = context | | window the same as the above code
    context.fn = thisContext. fn = this = myFun) //(context.fn = this = myFun) //(context.fn = this = myFun)
    const args = [...arguments].slice(1)// The first argument is context, to be removed
    constresult = context.fn(... args)delete context.fn
    return result
}
Copy the code

Handwritten apply

Note: The syntax and actions of this method are similar to those of the call() method, except that the call() method accepts a list of arguments, while the apply() method accepts an array of arguments.

/ / Function. The prototype. The apply () sample
function fun(arg1, arg2) {
  console.log(this.name)
  console.log(arg1 + arg2)
}
const obj = { name: 'Mr. Chen?' }
// Accept a list of arguments; Method executed immediately
fun.apply(obj, [1.2])

// Output: xiao Chen 3
Copy the code

Here’s what I remember: Apply starts with an A, the same as Array, so Apply passes arrays.

Function.prototype.myApply = function(context) {
    if (typeof this! = ='function') {
        throw new TypeError('Error..... ')
    }
    context = context || window
    context.fn = this
    let result
    if (arguments[1]) { result = context.fn(... arguments[1])}else {
        result = context.fn()
    }
    delete context.fn
    return result
}
Copy the code

Write a bind

Call () and apply() fix this and execute the function again. Bind () fix this and return a function that binds the new this without executing the function.

The bind() method creates a new function, and when bind() is called, this of the new function is specified as the first argument to bind(), and the remaining arguments will be used as arguments to the new function.

Function.prototype.myBind = function(context) {
    if (typeof this! = ='function') {
        throw new TypeError('Error.... ')}// returns a function that binds this, where we need to save this
    const _this = this
    const args = [...arguments].slice(1)
        // Return a function
    return function F() {
        // Since it returns a function, we can use new F() as a constructor
        if (this instanceof F) {
            return new_this(... args, ... arguments) }return_this.apply(context, args.concat(... arguments)) } }Copy the code

conclusion

The above is the content of this handwritten JS, which has realized its own simple version of call, apply and bind functions. However, there are still some flaws, which need further study.