For beginners, the keyword this is always elusive, very complex, but in fact, as long as you understand the key, there is no much trouble;

In fact, what this refers to in a function is based on two principles: whoever refers to it refers to it and the nearest principle;

Generally, the directivity of this can be divided into the following categories. Let’s look at specific examples

This keyword in ordinary functions

/ / sample
function f1(){
	this.a = 5;
}
f1();
console.log(window.a) / / 5;

/ / sample 2
var b = 10;
function f2(){
	this.b = 20;
}
f2();
console.log(window.b) / / 20;
Copy the code

The above two examples are ordinary functions that refer to window, so our conclusion is: ordinary functions in which this refers to Window

You might ask, doesn’t it say that this refers to the object that called it? The function executes itself. Shouldn’t this refer to the function itself?

In fact, when the function calls itself, it is equivalent to window.f1(); for example, f1() is equivalent to window.f1();

Since window calls it, this refers to window

Object this keyword

Again, let’s take a look at the following example:

/ / sample
var obj1 = {
	a : 5.f1 : function(){
		console.log(this.a) / / 5
		console.log(this === obj1) //true
	}
}
obj1.f1(); 

Copy the code

From the given examples we can see that when called function as attributes of the object to this point to point to the object itself, that is to say since you function all is me a properties object, you inside this point to me, of course, this point is a kind of implicit binding of this phenomenon, but if we remove the implicit binding?

Let’s change the example:

// This is an example of a variation
var obj2 = {
	a : 5.f2 : function(){
		console.log(this.a); //undefined
		console.log(this === obj2) //false}}var init = obj2.f2 // Focus here
init();
Copy the code

Again, who calls refers to who. As you can see from variation 1, obj.f2 doesn’t call f2 here, it just assigns the function to init, so f2 is no longer called by obj2, because f2 has been implicitly unbound

If this is not obj2, then obj2 cannot be called. If this is not obj2, then obj2 cannot be called.

So init() here, it calls a function, the variable is a global variable, and its top-level object is window in this case, so init() === window.init() is the same thing, so finally this refers to window;

It’s important to see where the function is called, so that we can figure out what this refers to, right

Change the above example again:

var obj3 = {
	a : 5.obj4 : {
		a : 10.f3 : function(){
			console.log(this.a) / / 10
		}
	}
}
obj3.obj4.f3();
Copy the code

Why is this output 10? The final call should be object obj3, so shouldn’t the a below it be 5?

Remember that word we used above called the proximity principle? Obj3 is called, but in the case of proximity, obj4 is called, so this refers to obj4 and must print 10

Finally, let’s add an example, which is something that someone had some questions about earlier, and I think it’s worth mentioning

var obj5 = {
	a : 5.f5 : function(){
		console.log(this.a) / / 5
		console.log(this === obj5) //true}}var init = obj5;
init.f5();
Copy the code

This is the same as obj5 calling f5. This is the same as obj5 calling f5

This keyword in call

Methods such as call(), bind(), and apply() bind this keyword, also known as display binding, and we can clearly see who it refers to

function f7(){
	this.x = function(){
		console.log(this.a) / / 20}}var obj5 = {
	a : 20
}
f7.call(obj5);
obj5.x();
Copy the code

With the call() method, the function f7 is encapsulated as a property of obj5, and the value of this refers to the calling object obj5.

From our use of the call() method, we know that if the first argument is null, or not written, then the object in between is window, as shown in the following example

function f8(){
	this.x = function(){
		console.log(this.a) / / 15}}var obj6 = {
	a : 20
}
var a = 15;
f8.call(null);
x();
// We can see that the function x is not defined in this section, but can be called directly here
// This refers to window, x() === window.x();
Copy the code

This keyword in the constructor

Take a look at an example:

function F1(){
	this.a = 10;
	this.b = 20;
	this.f6 = function(){
		this.c = this.a+this.b;
		console.log(this.c); / / 30
		console.log(this === F1) //false}}var oInit = new F1();
oInit.f6();
Copy the code

We need to know what new is doing in the process of new F1().

Look at the following code:

// The new process is as follows
{}
// create an empty object {}(first step)
{}.__proto__ = F1.prototype 
// Empty object implicit prototype points to F1 prototype object (step 2)
F1.call({});
// All attributes and methods in F1 are inherited from the call method. This step points F1's this to the empty object
// Then the empty object inherits the contents, at the end
return this; 
// This is returned by default when we do not actively change the return content (step 4)
//而Oinit = {}
// This naturally points to Oinit
Copy the code

I’ve seen a lot of people say that the “this” in a constructor refers to the constructor itself, which is not true, it doesn’t refer to the function itself, who’s going to call it, right? It points to an instance of new, so be careful here

There is a special case for using return in constructors, and let’s look at it

/ / sample
function f9(){
	this.a = 10;
	var obj10 = {};
	obj10.a = 20;
	return this.a
}
var init2 = new f9();
init2.a;


/ / sample 2
function f9(){
	this.a = 10;
	var obj10 = {};
	obj10.a = 20;
	return obj10;
}
var init2 = new f9();
init2.a;

Copy the code

This two sample is a bit special, special is that the return value, here regardless of this, pointing to the problem, tell me about a return value of the return of the problem, if the return is an object in the function (including function, array, object), the return is the object itself, will override this object, if the return is a value type, Return this object;

So it looks like the constructor’s instantiated object is calling the argument, but it is not. Internally, the constructor is calling the returned object, so this refers to the returned object

5. This keyword in the event

1. Use this directly in events

<div class="clickMe">click me</div>
<script>
	var clickDom = document.querySelector('.clickMe');

	clickDom.onclick = function(){
		console.log(this.className) //clickMe
	}
</script>
Copy the code

Here this refers to the element of the action event, so if we use this directly in the event, this refers to the element of the action event;

2. The function in the event uses this;

<div class="clickMe">click me</div>
<script>
	var clickDom = document.querySelector('.clickMe');

	clickDom.onclick = function(){
		function test(){
			console.log(this.className) //undefined
			console.log(this) //[object Window]
		}
		test();
	}
</script>
Copy the code

If the function in the event calls this, then it depends on who called it. Before you worry, let’s look at the following example:

<div class="clickMe">click me</div>
<script>
	var clickDom = document.querySelector('.clickMe');

	clickDom.onclick = function(){
		var obj7 = {
			a : 10.f7 : function(){
				console.log(this.a); / / 10
			} 
		}
		obj7.f7();
	}
</script>
Copy the code

Here we can be absolutely certain that even in the event, the “this” refers to the same principle, who calls to whom + nearest principle;

The event is followed by an anonymous function, which is called by the element in the event, so it is natural to refer to the element that called the event

Ok, about the directivity of this problem, that’s it, or the same sentence, who calls to whom + nearby principle, all are illusory, through the phenomenon to see the essence, can really know who this is pointing to


Original is not easy, summary is not easy, hand is not easy, please indicate the source when reprinting, thank you