解決this指代的三種常用方法

解決this指代的三種常用方法

JavaScript語言的this對象一直是一個令人頭痛的問題。在這裏,我們以一個簡單小例子來爲大家講解!

原文鏈接:https://editor.csdn.net/md/?articleId=105790363

直接上代碼:

class Animal {
    constructor() {
        this.type = 'animal';
    }
    says(say) {   
    	setTimeout(function() {
        	console.log(this.type + ' says ' + say);
    	}, 1000);
    }   
} 
var animal = new Animal();
animal.says('hello'); 
//輸出結果:undefined says hello
//注意:這裏的this指向的是全局作用域,所以是undefined

分析原因:一般情況下setTimeout()的this指向window或global對象;而當使用類的方法時,需要this指向類實例,以下三種方法可以將this綁定到回調函數來管理實例

解決方法一(傳統):賦值, 將this傳給self,再用self來指代this
class Animal {
   constructor() {
       this.type = 'animal';
   }
   says(say) {
       var self = this;
       setTimeout(function() {
           console.log(self.type + ' says ' + say);
       }, 1000);
   }
} 
var animal = new Animal();
animal.says('hello');
//輸出結果:animal says hello
解決方法二(ES5):bind(this)
class Animal {
   constructor() {
       this.type = 'animal';
   }
   says(say) {
       setTimeout(function() {
           console.log(this.type + ' says ' + say);
       }.bind(this), 1000);
   } 
} 
var animal = new Animal();
animal.says('hello');
//輸出結果:animal says hello
解決方法三(ES6):箭頭函數

注:箭頭函數不改變this指代

class Animal {
   constructor() {
       this.type = 'animal';
   }
   says(say) {
       setTimeout(() => {
           console.log(this.type + ' says ' + say);
       }, 1000);
   }
} 
var animal = new Animal();
animal.says('hello');
//輸出結果:animal says hello

下面咱們簡單瞭解一下什麼是bind()方法和箭頭函數!

原文鏈接:https://editor.csdn.net/md/?articleId=105790363

bind()

bind()方法,顧名思義,就是綁定的意思

bind()方法主要就是將函數綁定到某個對象,bind()會創建一個函數,函數體內的this對象的值會被綁定到傳入bind()第一個參數的值,即從第二個參數起,會依次傳遞給原始函數

例如:fn.bind(obj),言外之意就是 obj.fn(),fn函數體內的this自然就指向obj

語法:fn.bind(this,arg1,arg2,…);

小例子:

var a = {
	b:function(){
		var fn = function(){
			console.log(this.c+' '+'world');
		};
		fn();
	},
	c:'hello'
}
a.b();
// undefined world
//注:這裏的this指代的是全局作用域,所以返回undefined
bind()綁定一
var a = {
	b:function(){
		var fn = function(){
			console.log(this.c+' '+'world');
		}.bind(this);
		fn();
	},
	c:'hello'
}
a.b();
// hello world
//注:因爲該函數是一個對象的方法,則它的this指針指向這個對象
bind()綁定二
var a = {
	b:function(){
		var fn = function(){
			console.log(this.c+' '+'world');
		};
		fn.bind(this)();
	},
	c:'hello'
}
a.b();
// hello world
bind()傳入多個參數
function fn(y,z){
	return this.x+y+z;
}
var obj = {
	x:2
};
var num = fn.bind(obj,3,5);
console.log(num()); //10
//注:bind方法會把它的第一個實參綁定給fn函數體內的this,所以這裏的this即指向obj對象
//從第二個參數起,會依次傳遞給原始函數,即y=3,z=5

箭頭函數

箭頭函數是ES6新出來的寫法,它的語法比函數表達式更簡潔,並且沒有自己的this、arguments、super或new.target

箭頭函數不需要 function 關鍵字來創建函數,省略 return 關鍵字,繼承當前上下文的 this 關鍵字

箭頭函數表達式更適用於那些本來需要匿名函數的地方,並且它不能用作構造函數

箭頭函數小細節:

1.如果參數只有一個,可以省略()
/*匿名函數*/
let fn1 = function(a){
	return a*a;
}
console.log(fn1(5));//25

/*箭頭函數*/
let fn2 = n =>{
	return n*n;
}
console.log(fn2(5));//25
//注:雖然可以省略return,但爲了方便閱讀,建議保留return
2.如果return只有一條語句,可以省略{}
let fn = (a,b) => a + b;
console.log(fn(8,9));//17
3.不改變上下文的this指代
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="box1">按鈕1</div>
		<div id="box2">按鈕2</div>
		<script>
			let oBox1 = document.querySelector('#box1');
			let oBox2 = document.querySelector('#box2');
			
			console.log(this); //window
			
			//匿名函數
			oBox1.onclick = function(){
				console.log(this);
				//輸出:<div id="box1">按鈕1</div> 
				//this指代的是oBox1
			}
			
			//箭頭函數:不改變上下文的this指代
			oBox2.onclick = () =>{
				console.log(this); //window
			}
		</script>
	</body>
</html>

注:箭頭函數沒有單獨的this
如果是該函數是一個構造函數,this指針指向一個新的對象
在嚴格模式下的函數調用下,this指向undefined
如果是該函數是一個對象的方法,則它的this指針指向這個對象

原文鏈接:https://editor.csdn.net/md/?articleId=105790363

關於bind()和箭頭函數就簡單介紹到這裏,想深入瞭解還需要查看官方文檔!

學到很多東西的訣竅,就是一下子不要學很多 ——洛克

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章