At the beginning of learning this, I was very confused about the direction of this, and I always felt that I could not grasp the point. At the same time, the system analysis pointed to by this is also difficult for xiao Bai to understand.

After a period of time of summary, probably understood the direction of this in different cases, here to give you a summary wave, try to use simple language to understand the direction of this.

Front knowledge

What is this?

General concept: keywords in JavaScript, properties of the current environment execution context object.

Readable concept: this is the first argument you pass when you call a function. This is the first parameter of the call.

Three forms of a function call

f(p1, p2); // Equivalent to function.call(undefined, p1, p2)

obj.child.method(p1, p2);// Equivalent to object.child.method. call(object.child, p1, p2)

f.call(context, p1, p2); // This type of call is complete
Copy the code

This is the context in the code above, the context that is passed when you call a function.

thisPoints to several cases

When analyzing the following situations, you can combine fn.call() to get the answer, without deliberately remembering.

The first:f(p1, p2)

function f(){ console.log(this) } 
f()

// In this code, f() === f.call()
Copy the code

In the above example, the printed result is window. Why is that? Because the browser rules:

If you pass a null or undefined context, then the window object is the default context (in strict mode the default context is undefined).

If you want to change the value of this here, use the following code:

f.call(obj) // This becomes obj
Copy the code

The second:obj.child.method(p1,p2)

var obj = { foo: function(){ console.log(this) } } 
obj.foo()
Copy the code

Convert obj.foo() to obj.foo.call(obj), where this is obj.

The third: inclusion[]

Arr [0]()

function fn (){ console.log(this)}var arr = [fn, fn2] 
arr[0] ()Copy the code

Arr [0] can be assumed to be arr.0(). This form is similar to the aforementioned obj. Child-method (p1,p2). Arr [0] () – arr. 0 () – arr. 0. The call (arr), easy this = = = arr.

Fourth: the arrow function does notthis

There is no this in the arrow function, so if you see this in the arrow function, you can just think of it as this outside of the arrow function. Whatever this is on the outside, the this inside the arrow function is still the same, because the arrow function itself does not support this.

Fifth:EventHandler

When we add event listeners, we also encounter situations where we need to get this:

button.addEventListener('click' ,function handler(){
  console.log(this)})Copy the code

We can’t directly tell what this is from the previous call method, so we need to find the code in which the handler called it. Looking at the MDN document, you can see this description:

When you register an event for an element using addEventListener(), the this value in the handle is a reference to that element. This is the same value as the currentTarget property of the event parameter passed to the handle.

This is translated into understandable code:

handler.call(event.currentTarget, event) 
Copy the code

We can conclude that this is event.currenttarget.

Often meet test questions analysis

Through the above methods, we can determine the point of “this” in most cases. Here are some classic interview questions to reinforce it for you.

The first question

var a = {
  name:"The name in it".sayName: function(){
    console.log("this.name = " + this.name)
  }
}

var name = "Name outside";

function sayName(){
  var sss = a.sayName;
  sss(); 
  // this.name = ??? 
  // Select * from 'window' where 'name' = 'window' where 'name' = 'window'
  a.sayName(); 
  //this.name = ???
  // 解析 : a. sayname.call (a), this is a, this = name
  (a.sayName)(); 
  //this.name = ???
  Call (a).call(a).call(a).call(a)
  (b = a.sayName)(); 
  //this.name = ???
  This = window.name= window.name= window.name= window.name= window.name= window.name= window.name= window.name
}
sayName();
Sayname.call (), this is window, window.name = outside name

Copy the code

The second question

var length = 10; 
    function fn(){ 
    console.log(this.length)
} 

var obj = { 
    length: 5.method: function(fn){ 
    fn() arguments[0](); 
        } 
}; 

obj.method(fn, 1)

// Ask: what is the output?
Copy the code

Use the code conversion method to resolve the topic as follows:

var length = 10; 
    function fn(){ 
    console.log(this.length)
} 

var obj = { 
    length: 5.method: function(fn){ 
        fn() //fn. Call (undefined), this = window, window.length = 10
        arguments[0] ();Call (arguments), this=arguments, that is, [fn, 1], the array of two numbers, the result is 2}}; obj.method(fn,1) 
// obj. Method. call(obj, fn, 1), this = obj
// Combine window.length with [fn, 1] to get output 10, 2

Copy the code