Understand the direction of this in js thoroughly, without having to back hard.

Keywords: Javascript

First of all, it must be said that the direction of this is indeterminate when the function is defined. Only when the function is executed can it be determined who this is pointing to. In fact, this ultimately points to the object that called it. (There are some problems with this sentence, which will be explained later. Although most articles on the Internet say this, in many cases it will not be a problem to understand like that, but in fact that understanding is not accurate, so you will have a thoughtful feeling when you understand this), then I will go into this problem in depth.

Why do you want to learn this? If you've learned object-oriented programming, you know what to do, and in JavaScript you have to know it, not oh.

Example 1

function a() {
    var user = "Dream chase";
    console.log(this.user); //undefined
    console.log(this); //Window
}
a();

As we said above, this ultimately points to the object calling it, where function a is actually pointed out by a Window object, as demonstrated by the code below.

function a(){
    var user = "Dream chase";
    console.log(this.user); //undefined
    console.log(this);  //Window
}
window.a();

Like the above code, alert is actually a property of windows and is clicked out by windows.

Example 2

var o = {
    user:"Dream chase",
    fn:function(){
        console.log(this.user);  //Dream chase
    }
}
o.fn();

This this refers to object o here, because you call this FN through o.fn(), which naturally refers to object o. Here again, it is emphasized that the direction of this cannot be determined at the time of function creation. It is only at the time of call that you can decide who calls to whom you want to know this.

In fact, examples 1 and 2 are not accurate enough. The following example can override the above theory.

If you want to understand this thoroughly, you have to look at the next few examples

var o = {
    user:"Dream chase",
    fn:function(){
        console.log(this.user); //Dream chase
    }
}
window.o.fn();

This code is almost the same as the one above, but why is this not pointing to window here? If according to the theory above, this ultimately points to the object that called it. To start with, window is a global object in js. The variable we created actually adds attributes to windows, so we can use a windowpoint o object here.

Let's not explain why the code this above does not point to a window. Let's look at another code.

var o = {
    a:10,
    b:{
        a:12,
        fn:function(){
            console.log(this.a); //12
        }
    }
}
o.b.fn();

This is also the object o pointed out here, but also this did not execute it, then you will certainly say that what I said at the beginning is not all wrong? Actually, it's not. It's just inaccurate at the beginning. Next, I'll add a word. I believe you can thoroughly understand this problem.

1. If there is this in a function, but it is not called by the object of the previous level, then this is pointing to window. It needs to be explained here that this is not pointing to window in the strict version of js, but we will not discuss the strict version here. You want to know that you can search on the Internet by yourself.

2. If there is this in a function and the function is called by an object at a higher level, this is the object at the higher level.

3. If there is this in a function, it contains more than one object. Although this function is called by the outermost object, this points to only the object that is above it. Example 3 can prove that if you don't believe it, let's continue with a few examples.

var o = {
    a:10,
    b:{
        // a:12,
        fn:function(){
            console.log(this.a); //undefined
        }
    }
}
o.b.fn();

Although there is no attribute a in object b, this this also points to object b, because this only points to its superior object, whether there is something this wants in this object or not.

There is also a special case, such as the following:

var o = {
    a:10,
    b:{
        a:12,
        fn:function(){
            console.log(this.a); //undefined
            console.log(this); //window
        }
    }
}
var j = o.b.fn;
j();

this is pointing to window, isn't it a bit obscure? It's because you don't understand a sentence, which is just as important.

this always points to the object that called it last, that is, to see who called it when it was executed. Although the function fn in Example 4 is referenced by object b, it is not executed when assigning FN to variable j, so it points to window eventually. this is different from Example 3, which executes FN directly.

this is really the same thing when this talks about it, but it will point to different things in different situations. The summary above has some minor errors in each place, not to say errors, but different situations in different environments, so I can't explain it clearly at one time, only you can slowly experience it.

Constructor version this

function Fn(){
    this.user = "Dream chase";
}
var a = new Fn();
console.log(a.user); //Dream chase

The reason why object a can point out user inside function Fn is that the new keyword can change the direction of this, and point this this to object a. Why do I say a is an object, because using the new keyword is to create an object instance? To understand this, think of our example 3, where we created an instance of Fn with the variable a (equivalent to copying a Fn into object a), at this point, it is only created, not executed, and the function Fn is called on object a, so this points to object a naturally, then why there is user in object a, because you have copied an Fn function into object a, using the new keyword is equivalent to copying a copy.

In addition to the above, we can also change the direction of this by ourselves. For information on changing the direction of this by ourselves, see Summary of call,apply,bind methods in JavaScript This article details how we can manually change this direction.

Update a minor issue when this encounters return

function Fn()  
{  
    this.user = 'Dream chase';  
    return {};  
}
var a = new Fn;  
console.log(a.user); //undefined

Look at one more

function Fn()  
{  
    this.user = 'Dream chase';  
    return function(){};
}
var a = new Fn;  
console.log(a.user); //undefined

Come Again

function Fn()  
{  
    this.user = 'Dream chase';  
    return 1;
}
var a = new Fn;  
console.log(a.user); //Dream chase
function Fn()  
{  
    this.user = 'Dream chase';  
    return undefined;
}
var a = new Fn;  
console.log(a.user); //Dream chase

What does that mean?

If the return value is an object, this points to that returned object, and if the return value is not an object, this points to an instance of the function.

function Fn()  
{  
    this.user = 'Dream chase';  
    return undefined;
}
var a = new Fn;  
console.log(a); //fn {user:'dream chase'}

Another point is that although null is also an object, here this points to an instance of that function because null is special.

function Fn()  
{  
    this.user = 'Dream chase';  
    return null;
}
var a = new Fn;  
console.log(a.user); //Dream chase

Knowledge Point Supplement

  • The default this in the strict version is no longer window, but undefined.

  • The new operator will change the direction of the function this. Although we have explained it above, there is no in-depth discussion on this issue, and it is rarely said on the Internet, so it is necessary to mention it here.

function Fn(){
    this.num = 1;
}
var a = new Fn();
console.log(a.num); //1

Why does this point to a? First, the new keyword creates an empty object, and then automatically calls a function apply method to point this empty object, so that this inside the function will be replaced by this empty object.

Note: When you new an empty object, the internal implementation of js does not necessarily use the apply method to change the direction of this. I'm just making an analogy here.

Posted by ihsreal on Fri, 03 Dec 2021 12:05:17 -0800