current position:Home>Understanding of this in JavaScript

Understanding of this in JavaScript

2022-05-15 03:07:03Lu Rongtao

JavaScript in this The understanding of the

stay JavaScript Programming ,this Keywords are very important , It's hard to understand , Often confuse beginners , So let's talk about it today this keyword .

One .this Overview

this yes Javascript A key word of language , It represents the function runtime , An internal object generated automatically , Can only be used inside a function , As the function is used in different situations ,this The value of will change , But there is a general principle , That's it this Refers to the object that called the function .

summary : Who called this function ,this Point to the who ( object )

Two .this The direction of

because this It's inside the function , Detect... Through different functions this Basic direction .

1. If there is no object in front of the function to call , So point window, however ES5 Except for the new strict mode , Because in strict mode this Point to undefined.

 The code is as follows :
 Ordinary function :
function fn() {
	console.log(this); 
}
fn();//window
window.fn();//window
 analysis : Ordinary function direct call , Default inside this Is directed window, At the same time, we say that the function is also window The following method , So you can also pass window To call , But the results also point to window.

"use strict";// Add strict mode 
function fn() {
	console.log(this); //window
}
fn();//undefined
window.fn();//window
 analysis : Under strict mode, if you call the function directly , According to the strict pattern of grammatical behavior, change the this It's pointing undefined, but window To call still points to window


 Self executing functions :
!(function () {
	console.log(this); //window
})();
 analysis : The situation is consistent with the above , Because it's a sub call , That is, no previous object calls point to window, The strict mode points to undefined

 Function expression :
var Declared function expression , Consistent with the above .
var fn1 = function(){
 	console.log(this); 
}
fn1();//window
window.fn1();//window

let Declared function expression 
let fn1 = function(){
 	console.log(this); 
}
fn1();//window
window.fn1();// There will be an error  window.fn1 is not a function, because let The declared function expression is not window Here's how ,(let With block scope and temporary deadband )


2. Event handler , Methods in custom objects this Point to , Depending on who calls the function this Point to whose characteristics , there this All point to the object of the current operation .

document.onclick = function(){
	console.log(this);//document
}
 analysis : the reason being that document By event type click Triggered this function , So inside the function this Point to document, Event binding addEventListener It's the same thing .

const obj = {
	name:'zhangsan',
	age:18,
	showName:function(){
		console.log(this);// obj
		console.log(this.name);//zhangsan
	}
}
obj.showName();
 analysis : The principle is the same as above. Who called the function , intra-function this Point to the who , there showName yes obj Object , adopt obj Object call , So the point to obj object .

3. In the constructor this Point to

Because the appearance of a constructor is similar to that of an ordinary function , The main difference is the way it is called . When used new Operator when calling a function , This function always returns an object , Usually , In the constructor this Point to the object returned .

let MyClass = function(){ 
 	this.name = 'zhangsan'; 
}; 
let obj = new MyClass(); 
console.log(obj.name); //zhangsan 
 analysis : In the constructor this Point to the object returned 
 But with new When calling the constructor , One more thing to note , If the constructor explicitly returns a  object  Object of type , Then the result of this operation will eventually return this object , Not what we had before this.
let MyClass = function(){ 
     this.name = 'zhangsan'; 
     return { // Explicitly return an object 
        name: 'lisi' 
     } 
}; 
let obj = new MyClass(); 
console.log (obj.name); //lisi 
 If the constructor does not explicitly return any data , Or return a non object type data , It will not cause the above problems , Mainly new Keyword call function , The function implicitly returns this Caused by the .
let MyClass = function(){ 
     this.name = 'zhangsan' 
     return 'lisi';
}; 
let obj = new MyClass(); 
console.log(obj.name); //  Output :zhangsan

4. Arrowhead function this Point to .

ES6 Added arrow function , For ordinary functions , Inside this Point to the object where the function runs , But this is not true for arrow functions . It doesn't have its own this object , Inside this Is defined in the upper scope ( Parent scope ) Of this. in other words , Inside the arrow function this The point is fixed , by comparison , Of a normal function this The direction is variable .

const obj = {
	a:1
};
const fn = function () {
	alert(this.a);// Output 1, Because... Was modified during the call this Point to , therefore this Point to obj
};

fn.call(obj); // Originally this Point to window, adopt call( I'll explain it later ) change this Point to obj, The final this It becomes obj

const fn = () => {
	alert(this.a);// Output undefined, because window Not below a attribute .
};
fn.call(obj);// The arrow function is used in the code ,this Will not be affected , Still point to window

document.onclick = () => {
	alert(this); //window,this From the father , If there is no parent , Point to window
};

document.onclick = function () {
    alert(this); //document, because document This function was called 
    window.setInterval(() =>{
   		 alert(this); //document, Because the arrow function is used ,this Inside the function pointing to the outer layer this.
    }, 1000);
};

3、 ... and . modify this The way of pointing .

1. utilize call,apply,bind Method .

There are three methods below the function ,call,apply,bind Can change this The direction of , Let's demonstrate the application and difference of these three methods .

call Method :
call The first parameter of the method is the new this Point to ,  Starting with the second parameter, the parameter representing the function itself .
const obj = {
    a: 100,
};

function sum(x, y) {
	console.log(this.a + x + y);
}
sum(3,7);//underfined + 3 + 7 = NaN
 analysis : Call directly ,this Point to window,window Not below a attribute , therefore window.a yes undefined
sum.call(obj, 3, 7); //100 + 3 + 7 = 110
 analysis : adopt call change this, Make it point obj,obj Below has a attribute , therefore obj.a yes 100

apply Method :
apply The first parameter of the method is the new this Point to ,  The second parameter is an array or class array , The value inside is still the parameter of the function itself .
const obj = {
    a: 100,
};

function sum(x, y) {
	console.log(this.a + x + y);
}
sum(3,7);//underfined + 3 + 7 = NaN
 analysis : Call directly ,this Point to window,window Not below a attribute , therefore window.a yes undefined
sum.apply(obj, [3, 7]); //100 + 3 + 7 = 110  Notice that the brackets are apply The second parameter of must be array or class array .
 analysis : adopt apply change this, Make it point obj,obj Below has a attribute , therefore obj.a yes 100

call and apply Simple application of 
var obj1 = { 
 name: 'zhangsan' 
}; 
var obj2 = { 
 name: 'lisi' 
}; 
window.name = 'window'; 
var getName = function(){ 
 alert ( this.name ); 
}; 
getName(); //  Output : window 
getName.call( obj1 ); //  Output : zhangsan 
getName.call( obj2 ); //  Output : lisi
bind Method :
bind The first parameter of the method is the new this Point to ,  Starting with the second parameter, the parameter representing the function itself , but bind  Is to return the corresponding function body , Easy to call later ,apply、call Call immediately 
const obj = {
    a: 100,
};

function sum(x, y) {
	console.log(this.a + x + y);
}
sum(3,7);//underfined + 3 + 7 = NaN
 analysis : Call directly ,this Point to window,window Not below a attribute , therefore window.a yes undefined
sum.bind(obj, 3, 7)(); //100 + 3 + 7 = 110   Note that you need to call... Again 
 analysis : adopt bind change this, Make it point obj,obj Below has a attribute , therefore obj.a yes 100


bind Usage scenarios of 
 Case study : take fn intra-function this Point to obj object ,2s Post output this.num Value .
window.num = 100; //window Add attribute 
const obj = {
 	num: 1000
}

function fn() {
	console.log(this.num);
}

fn(); //100  there this Point to window
window.setInterval(fn.call(obj), 2000); // The timer at this time is invalid , Has called fn function ,
window.setInterval(fn.apply(obj), 2000); // The timer at this time is invalid , Has called fn function 
window.setInterval(fn.bind(obj), 2000); // The first parameter of the timer is the function body or function name ,bind What is returned is the function body , So meet the needs .

2. Will be right this Storage .

Through variables will be needed this Store it , Then use the stored... Inside the function this Achieve our goals .

window.num = 2;

function fn() {
	console.log(this.num);
}

const obj = {
    num: 1,
    shownum: function() {
        let _this = this;//  Through variables will be needed this Store it 
        return function() {
        	console.log(_this.num); // Call the stored this
        }
    }
}

obj.shownum(); 


3. Borrow methods from other objects

The first way to borrow a scene constructor is to borrow another scene constructor , Through this technology , You can achieve some inheritance like effects :

let A = function( name ){ 
 this.name = name; 
}; 
let B = function(){ 
 A.apply( this, arguments ); 
}; 
B.prototype.getName = function(){ 
 return this.name; 
}; 
var b = new B( 'zhangsan' ); 
console.log( b.getName() ); //  Output : 'zhangsan' 

The second scenario for borrowing other object methods is to borrow arguments

 We know the parameter list of the function arguments Is a class array object , Although it also has “ Subscript ”, But it's not really an array , So it can't be like an array , Sort or add a new element to the collection . In this case , We often borrow Array.prototype Method on object . For example, if you want to arguments Add a new element to , I usually borrow 
Array.prototype.push:
(function(){ 
 Array.prototype.push.call( arguments, 3 ); 
 console.log ( arguments ); //  Output [1,2,3] 
})( 1, 2 ); 
 In operation  arguments  When , We often look for... Very often  Array.prototype  Object borrowing methods .

Four . and this Interpretation of some relevant classic cases

var name = "The Window";
var object = {
    name : "My Object",
    getNameFunc : function(){
        return function(){
        	return this.name;
        };
    }
};
alert(object.getNameFunc()());//"The Window"
 analysis :
var The declared variable is window The following properties 
object There are methods in the object getNameFunc, And the return value of this method is also a function , You have to call... Again .
 Through the returned function, there is this, But here this Not through object To call , because object.getNameFunc() Returns a function body ( Ordinary function expressions ), You need to call the function body again , And calling again is like object The object has nothing to do with , So here this It doesn't point to object, It's pointing to window, Results output "The Window"

var name = "The Window";
var object = {
    name : "My Object",
    getNameFunc : function(){
        var _this = this;
        return function(){
        	return _this.name;
        };
    }
};

alert(object.getNameFunc()()); //"My Object"
 analysis :
 Most of the situation here is consistent with the above , The difference is that object.getNameFunc The method will point to... In advance object Object's this Stored as a variable , And this variable is used when returning the function body , So... In the returned function this Namely object.getNameFunc Method this, It points to object object , Results output  "My Object"

* Get Qianfeng education learning video materials + Source notes , Enter the learning exchange group
Please add wechat below ( remarks CSDN recommend )
 Please add a picture description

copyright notice
author[Lu Rongtao],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2022/132/202205112355553414.html

Random recommended