解決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()和箭頭函數就簡單介紹到這裏,想深入瞭解還需要查看官方文檔!
學到很多東西的訣竅,就是一下子不要學很多 ——洛克