This points to a detailed solution

directory

  • preface
  • First, the direction of this
  • Call and apply
  • Simulate a call
  • Fourth, the bind
  • Five, the end

preface

Remember when looking for an internship, always add a sentence on the resume – familiar with Js, such as this point to, call, apply…

I go through the following steps every time I submit a resume

  • Before the interview, ask baidu — what is the difference between “call” and “apply”? It went from 0% to 50%;
  • In the interview, the interviewer threw up a few questions, I can “firmly” give the answer, the result is always unsatisfactory…
  • After the interview, I shamed myself into deleting this item from my resume. And then when I sent out my resume, I added this again…

Since we know this knowledge point is important, this time we attack it 😊, let’s go! In my first article in June, IT was the first time FOR me to contact the mind brain map and try to apply it to my daily study. We are encouraged together!

First, the direction of this

Baidu, Google input “this point to” keyword, thousands of articles must be some, not in order to all aspects, no dead Angle master it will be all the articles read again? So let’s tease out a solid framework, and we’ll fill it in together.

Mind mapping

The essence of this section:

  • This always (in non-strict mode) points to an object, and which object it points to is function-based at run timeThe execution environmentDynamically bound, rather than the context in which the function is declared;
  • In addition to the infrequent cases of with and eval, this can be classified into four types:
    • Method calls as objects;
    • Called as a normal function;
    • Constructor call;
    • Call or apply;
    • In the arrow function, this points to this in the function’s upper scope;
  • The constructorandCommon functionThe difference betweenThe way it is called;
  • A,call(B) => A,call(B) =>

Analysis of the

1. Method calls as objects

When a function is called as a method of an object, this refers to that object

var obj = {
    a: 'yuguang'.getName: function(){
        console.log(this === obj);
        console.log(this.a); }}; obj.getName();// true yuguang
Copy the code

2. Called as a normal function

When a function is not called as an object property, but as a normal function, this always refers to the global object (in browsers, usually the Window object).

window.name = 'yuguang';

var getName = function(){
    console.log(this.name);
};

getName(); // yuguang
Copy the code

Or the confusing code below

window.name = 'Lao wang'
var obj = {
    name: 'yuguang'.getName: function(){
        console.log(this.name)
    }
};

var getNew = obj.getName;
getNew(); / / Lao wang
Copy the code

In ES5’s strict mode, this is specified not to refer to a global object, but to undefined

Constructor calls

With the exception of some built-in functions, most functions in Js can be constructors. Are they any different from normal functions

The difference between a constructor and a normal function is the way it is called: when the new operator calls a function, it always returns an object, and this usually refers to that object as well

var MyClass = function(){
    this.name = 'yuguang';
}
var obj = new MyClass()
obj.name; // yuguang
Copy the code

However, if an object is explicitly returned, the result of the operation will eventually return that object.

var MyClass = function () {
    this.name = 1;
    return {
        name: 2}}var myClass = new MyClass(); 
console.log('myClass.name:', myClass.name); // { name: 2}
Copy the code

As long as the constructor does not display any data, or returns data of a non-object type, this does not cause the above problem.

4. Call or apply

In contrast to normal function calls, call and apply can change this dynamically

var obj1 = {
    name: 1.getName: function (num = ' ') {
        return this.name + num; }};var obj2 = {
    name: 2,}Obj1.getname () is called in obj2's scope
console.log(obj1.getName()); / / 1
console.log(obj1.getName.call(obj2, 2)); // 2 + 2 = 4
console.log(obj1.getName.apply(obj2, [2])); // 2 + 2 = 4
Copy the code

5. Arrow function

The arrow function does not create its own this; it only inherits this from the upper level of its scope chain. Therefore, in the following code, the value of this in the function passed to setInterval is the same as that in the enclosing function:

this.name = 2
var obj = {
    name: '1'.getName: (a)= > {
        console.log(this.name)
    }
}

obj.getName()
Copy the code

The pit of common

Just like the title, sometimes this will point to undefined

Is a

var obj = {
    name: '1'.getName: function (params) {
        console.log(this.name)
    }
};
obj.getName();

var getName2 = obj.getName;
getName2()

Copy the code

When getName2() is called as a normal function, this points to the global object — window.

Case 2

When we want to wrap Dom methods ourselves to simplify code:

var getDomById = function (id) {
    return document.getElementById(id);
};
getDomById('div1') / / the dom node
Copy the code

So let’s see if we can write it this way?

var getDomById = document.getElementById
getDomById('div1') // Uncaught TypeError: Illegal Invocation (Illegal invocation)
Copy the code

This is because:

  • When we go to calldocumentObject to which this pointsdocument.
  • When we apply a method in document with getId and call it as a normal function, the this of the function content refers to the global object.

Use Call and apply to fix case two

document.getElementById = (function (func) {
    return function(){
        return func.call(document. arguments) } })(document.getElementById) 
// Save the document in scope with the immediate execution function
Copy the code

Call and apply

Do not resist it because of its “strong”, understanding and familiar with it is we must do, mutual encouragement!

Mind mapping

1. There is a difference between call and apply

Let’s look at the differences first, because they are almost indistinguishable, and the following code examples call and Apply can be easily toggled.

When they are designed to do exactly the same thing, the only difference is that the format of the parameters is different

  • Apply takes two parameters
    • The first argument specifies the point to the this object in the function body
    • The second argument is a set of arguments with a subscript (can be an array or array like)
  • Call accepts variable parameters
    • The first argument specifies the point to the this object in the function body
    • The second and subsequent arguments are the arguments to the function call

This is because in all (non-arrow) functions you can refer to the arguments of the function in the function via the Arguments object. This object contains each parameter passed to the function and is itself an array of classes, which we use more often in practice with Apply.

Call is the syntactic sugar wrapped above Apply, and we can use call if we explicitly know the number of arguments and want to display them.

When using Call or Apply, if the first argument we pass is null, this in the function’s body points to the host object by default, and window in the browser.

Borrowing methods from other objects

We can simply pass NULL instead of arbitrary objects

Math.max.apply(null[1.2.3.4.5])
Copy the code

2. What can call and apply do?

Call a function with a specified this value and one or more arguments given separately — to MDN

  • Call the constructorImplementation inheritance;
  • Calling the function and specifying the contextthis;
  • Call the function without specifying the first argument;

1. Call the constructor to implement inheritance

To achieve the effect of inheritance by means of borrowing:

function Product(name, price) {
	this.name = name;
	this.price = price;
}

function Food(name, price) {
	Product.call(this, name, price); //
	this.category = food;
}

var hotDog = new Food('hotDog'.20);
Copy the code

2. Call the function and specify the contextthis

This is now referred to obj

function showName() {
    console.log(this.id + ':' + this.name);
};

var obj = {
    id: 1.name: 'yuguang'
};

showName.call(obj)
Copy the code

3. Use call to simply call a function

Math.max.apply(null[1.2.3.10.4.5]); / / 10
Copy the code

Simulate a call

First, let’s see what call help us do.

var foo = {
	value: 1
};
function show() {
	console.log(this.value);
};
show.call(foo); / / 1
Copy the code

It’s like solving an equation, looking for a breakthrough in a given situation:

  • callMakes this point to foo;
  • showThe function is executed;
  • The parameter passed in should bethis+ Parameter list;

First edition code

The three points mentioned above are only a little done, and the parameters passed in

var foo = {
    value: 1
}
function show() {
    console.log(this.value);
}

Function.prototype.setCall = function (obj) {
    console.log(this); // This points to show
    obj.func = this; // Make the function an internal property of the object
    obj.func(obj.value) // Specify the function
    delete obj.func // Delete the function as if nothing happened ~
}
show.setCall(foo)
Copy the code

Second Edition code

To solve the argument problem, we need to be able to get the argument and pass it in correctly:

var foo = {
    value: 1
}
function show(a, b) {
    console.log(this.value);
    console.log(a + b)
}
Function.prototype.setCall = function (obj) {
    obj.fn = this; // Make the function an internal property of the object
    var args = [];
    for(let i = 1; i < arguments.length; i++){
        args.push('arguments[' + i + '] ');
    }
    eval('obj.fn(' + args + ') '); // Pass in parameters
    delete obj.fn; // Delete the function as if nothing happened ~
}

show.setCall(foo, 1.2); / / 1 3
Copy the code

At this point, we can use call with multiple arguments, but what if you only want to use one method?

Version 3 code

Function.prototype.setCall = function (obj) {
  var obj = obj || window;
  obj.fn = this;
  var args = [];
  for(var i = 1, len = arguments.length; i < len; i++) {
    args.push('arguments[' + i + '] ');
  }
  var result = eval('obj.fn(' + args +') ');
  delete obj.fn;
  return result;
};
// Test it
var value = 2;
var obj = { value: 1 };

function bar(name, age) {
  console.log(this.value);
  return {
    value: this.value,
    name: name,
    age: age
  }
}
bar.setCall(null); / / 2
console.log(bar.setCall(obj, 'kevin'.18));
Copy the code

Fourth, the bind

Bind ()** bind()**

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.

We’ll use Js to simulate a bind method to deepen our understanding

Function.prototype.bind = function (func) {
    var _this = this
    return function(){
        return _this.apply(func, arguments); }}var obj = {
    name: 1.getName: function(){
        console.log(this.name)
    }
}

var func = function(){
    console.log(this.name)
}
func.bind(obj)
Copy the code

Bind will always return the same this value

At the end

About me

  • Name: Afterglow
  • Draft design for a front end white who worked for less than a year
  • JavaScript version of LeetCode solution
  • LeetCode solve the CSDN address
  • Front-end advanced notes

This is my first attempt to expand knowledge by combining brain map and code instance, if you see the end, please bookmark, like and comment!!

Continue to update, your three even is my biggest power, humbly accept the big men’s criticism and advice, mutual encouragement!