When developing in JavaScript, many developers are somewhat confused by the reference to this, but in fact, remember the most important thing about this reference: which object calls the function, and which object this refers to. Let’s talk about it in a couple of ways

1. Plain function calls

There is nothing special about this case, it just points to the global object -window.

Function fn(){3, alert(this.username); //undefined 4,} 5, fn();Copy the code

You might wonder why I’m not printing wait, but if you take a closer look, I’m declaring let, not window if I’m printing wait, do I write it like this

Function fn(){3, alert(this.username); } 5, fu(); 6, / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 7, window. The username = 'cn' 8, function fn () {9, alert (enclosing the username); } 11, fn(); //window.fn();Copy the code

2. Object function calls

That’s not hard to understand, is that function call, where does this point to

Function (){1, function(){2, function(){2, function(){3, function(){3, function(); / / 111 6, alert (this. B); //undefined 7,} 8,} 9, obj.fn();Copy the code

Obviously, the first output is obj.a, which is 111. And the second time, obj doesn’t have b, so undefined, because this refers to obj.

But here’s something to watch out for

1, let obj1={2, a:222 3,}; 4, let obj2={5, a:1, 5, fn:function(){7, alert(this.a); } 9,} 10, obj1.fn=obj2.fn; 11, obj1. Fn (); / / 222Copy the code

Fn is assigned from obj2.fn, but obj1 is called, so this refers to obj1.

Constructor calls

1, let TestClass=function(){2, this.name='111'; } 4, let subClass=new TestClass(); 5, ttf_subclass. Name = 'cn'; 6, the console. The log (ttf_subclass. Name); 1, let subClass1=new TestClass(); 8, the console. The log (subClass1. Name) / / 111Copy the code

This is not difficult to understand, recall (new four steps) almost!

But there’s one pit, which doesn’t usually appear, but it’s worth mentioning.

Returning an object in a constructor returns the object directly, not the object created after executing the constructor

4. Apply and call

Apply and call are simply this that change the function passed in.

1, let obj1={2, a:222 3,}; 4, let obj2={5, a:1, 5, fn:function(){7, alert(this.a); } 9,} 10, obj2.fn. Call (obj1);Copy the code

Obj2 calls the method, but uses call to dynamically point this to obj1. Equivalent to this obj2.fn this execution environment is obj1. Apply and Call are detailed below.

5. Arrow function calls

First of all, WE have to say that ES6 provides arrow functions to increase our development efficiency, but in the arrow function, there is no this, the this in the arrow function inherits the external environment. A case in point

1.let obj={ 2. a:222, 3. fn:function(){ 4. setTimeout(function(){console.log(this.a)}) 5. } 6.}; 7.obj.fn(); //undefinedCopy the code

This refers to window. There is no A under the window, so undefined is printed here. I’m going to use the arrow function

Function (){4, setTimeout(()=>{console.log(this.a)}); 5,} 6,}; 7, obj. Fn (); / / 222Copy the code

This time 222 is printed because setTimeout is passed to the arrow function, and the arrow function doesn’t have this in it, so you have to look up the upper scope. In this case, setTimeout’s upper scope is FN. And fn’s this points to obj, so setTimeout’s arrow function this points to obj. So the output 222

6, Call and apply

Call and apply work exactly the same, except for parameters. Call takes a variable number of arguments. The first argument is a reference to this in the function body, and the second argument is passed in sequence. Apply takes two arguments, the first of which is also a reference to this inside the function. The second argument is a collection object (array or class array)

1, let fn=function(a,b,c){2, console.log(a,b,c); 3,} 4, let arr=[1,2,3];Copy the code



Take this example above

1, let obj1={2, a:222 3,}; 4, let obj2={5, a:1, 5, fn:function(){7, alert(this.a); } 9,} 10, obj2.fn. Call (obj1);Copy the code

The two main uses of call and apply are

1. Redirect this (from obj2 to obj1)

2. Method borrowing (obj1 has no fn, just borrows obj2 methods)