The apply() method calls a function by taking a specified this value and an array of arguments.

The call() method takes a specified this value and a list of arguments to call a 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

When using the Call and apply functions, be aware that if the value passed to this is not an object, JavaScript will attempt to convert it to an object using the internal ToObject operation. So, if the value passed is a raw value like 7 or ‘foo’, then the relevant constructor will be used to convert it to an object, so the raw value 7 will be converted to an object like new Number(7), and the String ‘foo’ will be converted to new String(‘foo’), Such as:

function bar() {
  console.log(Object.prototype.toString.call(this));
}

// The original value 7 is implicitly converted to an object
bar.call(7); // [object Number]
bar.call('foo'); // [object String]
Copy the code

apply

func.apply(thisArg, [argsArray])

  • thisArgWill be selected. infuncUsed when the function is runthisValue. If this function is inNonstrict modeUnder, the value isnullundefinedIs automatically replaced with a reference to a global object, and the original value is wrapped.
  • ArgsArray optional. An array or array-like object whose array elements are passed as individual argumentsfuncFunction.
Function.prototype.Apply = function (thisArg, args = Symbol.for('args')) {
  // The Apply function is always called by the function we want to change this, so within this function this always refers to the calling function
  
  // Generates a unique Symbol of type Symbol that is used to mount the apply function on the specified object
  const fn = Symbol('fn')      
  thisArg[fn] = this  

  // Call the function from the object and pass the parameter
  args === Symbol.for('args') ? thisArg[fn]() : thisArg[fn](...args)

  // Deletes the method mounted to the specified object
  delete thisArg[fn]           
}

// Declare global variables
var position = 'global'
var name = 'window'

function func(name) {
  console.log(this.position)
  console.log(name) 
}

const obj = {
  name: 'object'.position: 'obj',
}

func.Apply(obj,[obj.name,null]) // obj object
// This points to func in Apply

func.Apply(obj,[name,null]) // obj window
// name in func is only affected by the pass parameter
Copy the code

Symbol.for(key) finds the corresponding Symbol from the run-time Symbol registry based on the given key key. If it is found, it is returned; otherwise, a new Symbol associated with the key is created and placed in the global Symbol registry.

call

Function.prototype.Call = function (thisArg, ... args) {
  // where this is the caller of this method
  const fn = Symbol('fn')
  thisArg[fn] = this || globalThis

  // Call the function from the object and pass the parameterargs.length ? thisArg[fn](... args) : thisArg[fn]()// Deletes the method mounted to the specified object
  delete thisArg[fn]      
}

func.Call(obj)  // obj undefined
func.Call(obj, 'test') // obj test
Copy the code

You don’t use the Arguments object here to get the incoming arguments. Arguments is not an Array and has no Array attributes other than the length attribute and index element.

Using the remaining parameters… Args can simplify code

bind

The bind() function creates a new binding function that wraps the function object. Calling a binding function usually results in the execution of a wrapper function.

Simple version

Function.prototype.Bind = function(thisArg, ... args){
  let self = this;
  let fBound = function(. args1){
    return self.apply(thisArg, [...args, ...args1]);
  }
  return fBound;
}
Copy the code

Closures are used to preserve the value of this from the first binding while invalidating subsequent bindings

Function.prototype.Bind = function(thisArg, ... args){
  let self = this;
  
  let fBound = function(. args1){
    // If this is an instance of fBound, new is executed, pointing to this, otherwise to the bind object
    return self.apply(this instanceof fBound ? this : thisArg, [...args, ...args1]);
  }
  // Change the prototype of the return function to the prototype of the binding function. The new instance object can inherit the members of the binding function prototype
  fBound.prototype = this.prototype;
  return fBound;
}
Copy the code

This is supplemented by the case where the bound function is a constructor

function foo(age, height) {
  console.log(this.name)       // obj
  console.log(age)             / / 3
  console.log(height)          / / 2
}
const obj = {
  name: 'obj'.age: 3
}
foo.Bind(obj, obj.age)(2) // Bind with a single argument
Copy the code

This pointer and arrow function is used to build a base from scratch

If you learn something new, please give the author a thumbs up