What should I get myself for programmer’s Day? Be prepared to work overtime.

Preface: In the front-end interview, the most common interview questions

  1. What does this point to?
  2. How do I change this?
  3. What is the difference between call, apply and bind?

If the interviewer asks you about the direction of this, you should guide the interviewer and ask him how to change the direction of this, the difference between call, apply and bind, and the source code parsing. In this way, you will have the initiative in your hands. Change the “this” reference to call, the difference between apply and bind, and the source code parsing. Hee hee ~

We know that in javascript, call and apply and bind can change this, so what’s the difference? So how do they work?

First, let’s talk about the use of call, apply, and bind

Call, apply and bind

  • call(this,… arguments);
  • apply(this,[arguments]);
  • bind(this, … arguments)(… newarguments);

A little bit more about the differences

Second, the difference between

  • The first argument to call() is the same as to apply(), which is the specified object. This object is the execution context of the function.

  • The difference between call() and apply() is the argument between the two. All subsequent arguments to call() after the first argument are the values passed to the function. Apply () takes only two arguments, the first an object and the second an array, which are arguments to the function.

  • The bind() method differs from the other two in that bind() returns the function whose execution context has been changed and does not execute it immediately, whereas the former two execute the function directly. Its arguments are the same as call().

Finally, look at the source code parsing

Three, source code analysis

1. Call () source code parsing

Function.prototype.myCall = function(context) { if (typeof this ! = = 'function') {throw new TypeError (' Error ')} context = context | | the window / / who call call method, Context.fn = this const args = [...arguments].slice(1) const result = context.fn(... arguments) const args = [...arguments].slice(1) const result = context.fn(... args) delete context.fn return result }Copy the code

Here’s an analysis of the call() implementation:

  1. Context is optional. If not, the default context is Window.
  2. Next create a fn property for the context and set the value to the function you want to call, namely this;
  3. Because call can pass multiple arguments as arguments to the calling function, you need to strip out the arguments by removing the first of all arguments (the specified object);
  4. Then call the function and remove the function fn from the object;

2, apply() source code parsing

The implementation of Apply is similar to call, except for the handling of parameters.

Function.prototype.apply = function (context) { if (typeof this ! = = 'function') {throw new TypeError (' Error ')} context = context | | window context. The fn = this let the result / / processing parameters and the call If (arguments[1]) {result = context.fn(... arguments[1]) } else { result = context.fn() } delete context.fn return result }Copy the code

Here’s an analysis of the apply() implementation:

  1. Context is optional. If not, the default context is Window.
  2. Next create a fn property for the context and set the value to the function you want to call, namely this;
  3. The second argument to apply is an array. This is the difference between apply and call.
  4. Then call the function and remove the function fn from the object;

3, bind() source code parsing

The implementation of BIND is a little more complicated than the other two functions, because bind needs to return a function and determine some boundary issues. Here is the implementation of BIND

Function.prototype.bind = function(context) { if (typeof this ! == 'function') {throw new TypeError('Error')} const _this = this const args = [...arguments].slice(1 Function F() {// If (this instanceof F) {// Ignore this return new _this(... args, ... Return _this.apply(context, args. Concat (... arguments)) } }Copy the code

Here’s an analysis of the bind() implementation:

  1. Context is optional. If not, the default context is Window.
  2. Next create a fn property for the context and set the value to the function you want to call, namely this;
  3. The bind and call arguments are the same. Multiple arguments can be passed as arguments to the call function, so you need to strip out the arguments by removing the first argument (the specified object) of all arguments.
  4. Bind returns a function that can be called either directly or through new.
  5. For direct calls, the apply approach is chosen, but for parameters note the following: Since bind can implement code like f.bind(obj, 1)(2), we need to concatenate the arguments on both sides, resulting in the implementation of args.concat(… arguments);
  6. By new, in the case of new, this will not be changed in any way, so in that case we need to ignore this;

it’s over.

Conclusion: Thank you for your reading, I hope this article is helpful to you, there are insufficient places above, welcome to correct!! Some of the content of the article comes from the way of front-end interview, if there is infringement, please contact the author to delete, small volume is very good yo ~! Finally in this festival, I wish all programmers no bugs, to lovely programmers salute!