The analysis of this direction in ordinary function and arrow function

Time:2020-11-26

Content

  • This of ordinary functions
  • This of arrow function

Ordinary function

1. Conclusion

Let’s start with the conclusion,The direction of this of an ordinary function cannot be determined when the function is defined. Only when the function is executed can we determine who this is pointing to. In fact, this ultimately points to the object calling it, and it is the nearest one

2. Analysis

Example 1:

function a(){ 
    Var user = function internal a;
    console.log(this.user); //undefined
    console.log(this); //Window
}
a();

We know that the call mode like this is called by window, so the output is as above, and verify it

Example 2:

Var user = a of window;
function a(){ 
    Var user = function internal a;
    console.log ( this.user ); // a of window
    console.log(this); //Window
}
a();

There is nothing in front of a (). The default window. A () is window. The caller is window, so “a of window” is output at this time

Example 3:

var o = {
    User: "dream chaser",
    fn:function(){
        console.log ( this.user ); // dream chaser
 }
}
o.fn();

Here, this points to the object o, because you call this FN through o.fn(), which naturally points to the object O. here again, the direction of this cannot be determined when the function is created. It can be decided when the function is called, and it can be decided when calling. It is necessary to make clear this.

Example 4:

Var user = "window dreamer"
var o = {
    User: "dream chaser",
    fn:function(){
        console.log ( this.user ); // dream chaser
 }
}
window.o.fn();

Although the outermost layer is a window call, the output this is the object o, which is the same as the conclusion I mentioned above,And it’s the last object that calls this

Example 5:

var o = {
    User: "dream chaser",
    fn:function(){
        console.log(this) // o
        setTimeout(function(){
            console.log(this);  //window
        },1000)
        
 }
}
o.fn();

FN is triggered by object o, so o is output,The timer and delayer queue are triggered by the window, so the output window

Arrow function (hit blackboard, emphasis)

1. Conclusion

  • The direction of this is confirmed in the definition, which is completely different from the normal function when it is used
  • Scope always points to the previous, last, last (very important, say three times)!
  • The object that the current scope points to last is the point of this

PS: the scope of JS generally refers to the function scope and global scope. The use of let type block level scope does not count

2. Analysis

Example 1:

var b=11;
var obj={
 b:22,
 say:()=>{
 console.log(this.b);
}
}
obj.say (); // the output value is 11

Say is an arrow function. The previous scope of the current scope is global, and the global refers to window, so the output is 11

Example 2:

var b=11;
var obj={
 b:22,
 say:function(){
  return () => {
     console.log(this.b);
  }
 }
}
obj.say () (); // the output value is 22

The return in say is the arrow function. The previous scope of the current scope is the say function, and then the scope of the say function refers to obj, so the output is 22

Example 3:

var str = 'window';  
 
const obj = {
    str:'obj',
    fn: ()=>{
    console.log(this.str);    
    },
    fn2: function(){
    console.log(this.str)
    return {
        str: 'newObj',
        fn: ()=>{
        console.log(this.str);    
        }    
    }
    }
}
 
obj.newFn = ()=>{
    console.log(this.str);    
}
 
obj.fn(); //window
obj.newFn(); //window
obj.fn2 (). Fn(); // output obj, obj
  1. The upper level of FN is global, so it is window
  2. Newfn is defined outside, but parsing is the same as FN
  3. FN2 is triggered by obj, so it outputs obj. An object is returned in FN2. There is a FN arrow function in the object. The upper scope of this FN is FN2 (don’t be confused by newobj here). The object that FN2 points to is obj, so the output is still obj

Example 4:

var obj = {
  str:'obj',
  fn: function(){
   return {
    str: 'inlineObj',
    fn1: function(){
     console.log(this.str); 
     return ()=>{
      console.log(this.str); 
     }
    },
    fn2: ()=>{
     console.log(this.str); 
    }
   }
  }
 }
 
 obj.fn (). FN1 () (); // output inlineobj, inlineobj
 obj.fn (). Fn2(); // output obj

One obj.fn () notice that an object has been returned, so when FN1 is triggered, inlineobj is output, and an arrow function is returned in FN1. The upper scope is FN1, and FN1 points to the {} of return, so the output is also inlineobj
2. The upper scope of FN2 is FN, which points to obj, so obj is output

Change the direction of this

Ordinary functions can be changed

Var user = a of window;
function a(){ 
    Var user = function internal a;
    console.log(this.user);
}
var obj = {
    User: 'obj's a'
}
A () // a of window
a. Call (obj) // a of obj

The arrow function cannot be changed

var obj = {
  str:'obj',
  fn: function(){
    console.log(this.str)
   },
  fn2: function(){
    return () => {
        console.log(this.str)
    }
    
  }
}
var obj2 = {
    str:'obj2'
}
obj.fn()  //obj
obj.fn.call(obj2) //obj2
obj.fn2()() //obj
obj.fn2().call(obj2) //obj

As you can see, even if the arrow function changes the direction of this with call, the output is still the original defined range

Some of them are special

Click event

< div id = "Dianji" > Click event < / div >

document.getElementById('dianji').addEventListener('click',function(){
    console.log (this); // output DOM
 })
document.getElementById('dianji').addEventListener('click',() =>{
    console.log(this); // window
 })

. addeventlistener is preceded by Dom, so when a normal function is triggered, the DOM will be output, and whoever calls the output will be output. However, the upper level scope of arrow function is global, so window is output

When this encounters return

Return null object {}

function fn()  
{ 
    this.user  ='dream chaser '; 
    return {};  
}
new fn().user    //undefined

Return function

function fn()  
{ 
    this.user  ='dream chaser '; 
    return function aaa(){};
}
new fn().user    //undefined

Return number

function fn()  
{ 
    this.user  ='dream chaser '; 
    return 1;
}
New fn(). User // dream chaser

Returns null

function fn()  
{ 
    this.user  ='dream chaser '; 
    return null;
}
New fn(). User // dream chaser

The main description of the above column
If the return value is a reference data type (function and object belong to object), then this refers to the returned object. If the return value is not an object (basic data type, numeric value, string, Boolean, null, undefined), then this is also an instance of the directed function.

Thanks
Thank you very much for your articles
Thoroughly understand the direction of this in JS, there is no need to memorize it.
Detailed explanation of this direction of ES6 arrow function
[ES6] two examples show that the arrow function this points to
This direction of arrow function in ES6