This detailed explanation and related 7 interview questions

foreword

When I read the scriptures, I found that my pointing to this was still a little vague. After reading a lot of this related articles, I plan to write an article to sort out this related knowledge , and use some common interview questions to strengthen my understanding for review and consolidation.

If you think the article is ambiguous, please point it out to avoid misleading more people! !


text

this

In the JavaScript language, everything is an object, and the runtime environment is also an object. Functions all run in an object, and this is the object (environment) where the function runs .

Why does this appear? Because functions can be executed in different operating environments, the appearance of this is to obtain (function) the current operating environment inside the function .

However, JavaScript supports dynamic switching of the runtime environment , which means that the pointing of this is dynamic, and there is no way to determine which object it points to in advance. This requires us to pay extra attention to the running environment of the function.

Let's take an example first ( from the article of Ruan Yifeng's predecessors ), although they are all executing foo. But the execution environment is not the same.

  • For obj.foo()example, foo runs in the obj environment, so this points to obj;
  • For foo()example, foo runs in the global environment, so this points to the global environment.
var obj = {
    
    
  foo: function () {
    
     console.log(this.bar) },
  bar: 1
};

var foo = obj.foo;
var bar = 2;

obj.foo() // 1
foo() // 2

If you want to understand this problem more deeply, you must understand the data structure of memory. The following picture is from Ruan Yifeng's this principle

var obj = {
    
     foo: function () {
    
    } };

For the code above, the variable obj is an address. If you want to read obj.foo, you must first get the memory address from obj, then read the original object from this address, and return its foo property.

The original object is stored in a dictionary structure, and each attribute name corresponds to an attribute description object. The value of the foo property is stored in the value property of the property description object. The function is stored separately in memory, and then the address of the function is assigned to the value property of the foo property.
insert image description here
So, a function is a single value , so it can be executed in a different environment (context), and JavaScript allows to reference other variables of the current environment inside the function body.


Use environment

global environment

When 全局环境using this, it refers to the top-level object window. Whether it is inside a function or not, as long as it is running in the global environment, this refers to the top-level object window.

console.log(this === window); // true
function f() {
    
    
    console.log(this === window); //true
}
f() // true

If strict mode is used "use strict";, it isundefined

function f(){
    
    
     "use strict";
     console.log(this);
 }
 f() //undefined

Constructor

构造函数This in , refers to the instance object.

 var Obj = function (p) {
    
    
      this.p = p; 
      console.log(this);
  };
  var o = new Obj('Hello World!');
  console.log(o.p); // "Hello World!"

insert image description here

object

If an object's method contains this, this points to the object where the method was run. Assigning this method to another object will change the pointer of this. Such as the following example

var a = 20; 
var obj = {
    
    
    a: 10,
    getA: function () {
    
    
        return this.a;
        }
}
console.log(obj.getA());    //10
var test = obj.getA;
console.log(test());        //20   独立调用test

Notice! ! ! The following usage will change the pointing of this . obj.foo is a value. When this value is actually called, the runtime environment is no longer obj, but the global environment, so this no longer points to obj.

var obj ={
    
    
  foo: function () {
    
    
    console.log(this);
  }
};
(obj.foo = obj.foo)() // window

In addition, if the method where this is located is not in the first layer of the object, then this only points to the object of the current layer, and will not inherit the upper layer . As follows, a.b.mthe method is in the second layer of the a object, the this inside the method does not point to a, but points to ab

var a = {
    
    
  p: 'Hello',
  b: {
    
    
  m: function() {
    
    
          console.log(this.p);
      }
  }
  };

  a.b.m() // undefined

show binding

The article can be viewed:

Front-end interview high-frequency questions - hand tearing call(), apply() and bind() function codes, understand the default binding, implicit binding and explicit binding of this function

Related interview questions

1

var m = 10;
function fn() {
    
    
    return this.m + 1;
}
var obj = {
    
    
    m: 5,
    test1: function() {
    
    
        return fn();
    }
};
obj.test2 = fn;
 
console.log(obj.test1(), fn(), obj.test2()) // 11 11 6

If you turn var into let the answer is: NaN NaN 6. The first two this.mare undefined, because the m declared with let belongs to the scope of the script, not windowsthe property on the body.
insert image description here

2

var obj = {
    
       
    a: 10,
    b: this.a + 10, //这里的this指向window(全局),a为undefined  ==>  undefined + 20 = NaN
    fn: function () {
    
    
        return this.a;
    }
}
console.log(obj.b);        //NaN
console.log(obj.fn());    //10

3

var a = 5;
 function fn1(){
    
    
     var a = 6;
     console.log(a);        //6
     console.log(this.a);   //5
 }  
 function fn2(fn) {
    
    
     var a = 7;
     fn();
 } 
 var obj = {
    
    
         a: 8,
         getA: fn1
     }  
 fn2(obj.getA); 

4

// 构造函数 
 function Person(name, age) {
    
    
     this.name = name;
     this.age = age;
     console.log(this); //Person实例对象
 }   
 Person();           //window
 Person.prototype.getName = function () {
    
    
     console.log(this);    //Person实例对象
 }; 
 var p1 = new Person("test", 18);
 p1.getName();

5

 var obj = {
    
    
     foo: "test",
     fn: function(){
    
    
         var mine = this;
         console.log(this.foo);       //test
         console.log(mine.foo);       //test
         
         (function(){
    
    
             console.log(this); // window
             console.log(this.foo);    //undefined
             console.log(mine.foo);    //test
         })();  
     } 
 };
 obj.fn();

6

function test(arg) {
    
    
     this.x = arg;
     return this;
 } 
 var x = test(5);     //此时 x = window, y = undefined
 var y = test(6);     //此时 x = 6,  y = window 
 console.log(x.x);     //undefined,   6.x是undefined
 console.log(y.x);     //6     实际上是window.x 也就是6

7

var obj = {
    
    
    data: [1,2,3,4,5],
    data2: [1,2,3,4,5],
    fn: function () {
    
    
       console.log("--test--");
       console.log(this);   //Object
       return this.data.map(function (item) {
    
    
             console.log(this);     //window
             return item * 2;
        }); 
    },
    fn2: function () {
    
    
       console.log("---test2---");
       console.log(this);     //Object
       return this.data2.map(item=>{
    
    
           console.log(this);   //Object
           return item * 2; 
       });
    }
 };  
 obj.fn();
 obj.fn2();

If you find this article useful, please like and subscribe! !

Guess you like

Origin blog.csdn.net/qq_45890970/article/details/123734078