我們在初使用 JavaScript 開發的時候,多多少少會被 this
的指向搞蒙圈,弄不清楚this指向哪一個物件,但是實際上,關於 this
的指向,記住最核心的一句話:
哪個物件呼叫函式,函式裡面的this指向哪個物件。
對this的討論,主要分以下幾種情況:
一、普通函式呼叫
二、物件函式呼叫
2.物件的方法 this指向的是物件 o
var o = { sayHi: function() { console.log('物件方法的this:' + this); } } o.sayHi(); //this指向的是物件 o
三、建構函式呼叫
3. 建構函式 this 指向 ldh 這個例項物件 原型物件裡面的this 指向的也是 ldh這個例項物件.
四、定時器函式呼叫與立即執行函式呼叫
// 5. 定時器函式 this 指向的也是window window.setTimeout(function() { console.log('定時器的this:' + this); }, 1000); // 6. 立即執行函式 this還是指向window (function() { console.log('立即執行函式的this' + this); })();
五、ES6中箭頭函式的呼叫
箭頭函式不繫結this即箭頭函式沒有自己的this,如果在箭頭函式中使用this,this關鍵字將指向箭頭函式中定義位置中的this
function fu() { console.log(this); return () => { console.log(this); } } const obj = { name: '張三', age: 20 } const resfn = fu.call(obj) resfn()
效果如下:
六、call()和apply()與bind()呼叫
<script> var o = { name: 'andy', } function fu(a, b) { console.log(this); console.log(a + b); } fu.call(o, 1, 2); // call 第一個可以呼叫函式 第二個可以改變函式內的this 指向 // call 的主要作用可以實現繼承 function Father(uname, age, sex) { this.uname = uname; this.age = age; this.sex = sex; } function Son(uname, age, sex) { Father.call(this, uname, age, sex); } var son = new Son('劉德華', 18, '男'); console.log(son); </script>
效果圖如下:
6.2apply()也是可以呼叫函式 ,第二個作用也可以改變函式內部的this指向,但是apply()的第二個引數必須是陣列(偽陣列)
// 2. apply() 應用 運用的意思 var o = { name: 'andy' } function fu(arr) { console.log(this); console.log(arr); //列印的是字串 } fu.apply(o, ['pink']); // 1. 也是呼叫函式 第二個可以改變函式內部的this指向 // 2. 但是他的引數必須是陣列(偽陣列) // 3. apply 的主要應用 比如說我們可以利用 apply 藉助於數學內建物件求陣列最大值 // Math.max(); var arr = [1, 66, 3, 99, 4]; var max = Math.max.apply(Math, arr); var min = Math.min.apply(Math, arr); console.log(max, min);
效果如下:
6.3 bind()不會呼叫原來的函式 ,但是可以改變原來函式內部的this 指向,呼叫該函式是有返回值的,返回的是原函式改變this之後產生的新函式
var o = { name: 'andy' }; function fn(a, b) { console.log(this); console.log(a + b); }; var f = fn.bind(o, 1, 2); f();
效果如下:
bind函式用的較多,如果有的函式我們不需要立即呼叫,但是又想改變這個函式內部的this指向此時用bind,比如我們有一個按鈕,當我們點選了之後,就禁用這個按鈕,3秒鐘之後開啟這個按鈕(類似於60s傳送簡訊驗證)
var btn = document.querySelector("button"); btn.onclick = function() { // var that = this; this.disabled = true; // 這個this 指向的是 btn 這個按鈕 setTimeout(function() { // that.disabled = false;定時器函式裡面的this 指向的是window this.disabled = false; // 此時定時器函式裡面的this 指向的是btn }.bind(this), 3000) // 這個this 指向的是btn 這個物件 }
七、call()和apply()與bind()總結
相同點:都可以改變this指向
不同點: call 和 apply 會呼叫函式, 並且改變函式內部this指向 ,call傳遞引數使用逗號隔開傳遞,apply傳遞第二個引數使用陣列傳遞, bind 不會呼叫函式
應用場景: call 經常做繼承, apply 經常跟陣列有關係. 比如藉助於數學物件實現陣列最大值最小值 ,bind 不呼叫函式,但是還想改變this指向. 比如改變定時器內部的this指向
好了,關於js中this的指向問題就介紹到這裡啦。如果你發現文中有錯誤的地方,還希望大佬們指正,共同進步