JS this指向總結
使用 JavaScript 開發的時候,很多開發者多多少少會被 this
的指向搞蒙圈,但是實際上,關於 this
的指向,記住最核心的一句話:哪個對象調用函數,函數裏面的this指向哪個對象。
下面分幾種情況談論下
1、普通函數調用
這個情況沒特殊意外,就是指向全局對象-window。
let username=‘cn‘ |
可能大家會困惑,為什麽不是輸出守候,但是在細看一看,我聲明的方式是let,不會是window對象
var username=‘cn‘ |
2、對象函數調用
這個相信不難理解,就是那個函數調用,this指向哪裏
window.b=2222 let obj={ a:111, fn:function(){ alert(this.a);//111 alert(this.b);//undefined } } obj.fn(); |
很明顯,第一次就是輸出obj.a,就是111。而第二次,obj沒有b這個屬性,所以輸出undefined,因為this指向obj。
但是下面這個情況得註意
let obj1={ a:222 }; let obj2={ a:111, fn:function(){ alert(this.a); } obj1.fn=obj2.fn; obj1.fn();//222 |
這個相信也不難理解,雖然obj1.fn是從obj2.fn賦值而來,但是調用函數的是obj1,所以this指向obj1。
3、構造函數調用
let TestClass=function(){ this.name=‘111‘; } let subClass=new TestClass(); subClass.name=‘cn‘; console.log(subClass.name);//cn let subClass1=new TestClass(); console.log(subClass1.name)//111 |
這個也是不難理解,回憶下(new的四個步驟)就差不多了!
但是有一個坑,雖然一般不會出現,但是有必要提一下。
在構造函數裏面返回一個對象,會直接返回這個對象,而不是執行構造函數後創建的對象
apply和call調用
apply和call簡單來說就是會改變傳入函數的this。
let obj1={ a:222 }; let obj2={ a:111, fn:function(){ alert(this.a); } } obj2.fn.call(obj1);復制代碼 |
此時雖然是 obj2 調用方法,但是使用 了call,動態的把 this 指向到 obj1。相當於這個 obj2.fn 這個執行環境是 obj1 。apply 和 call 詳細內容在下面提及。
5、箭頭函數調用
首先不得不說,ES6 提供了箭頭函數,增加了我們的開發效率,但是在箭頭函數裏面,沒有 this ,箭頭函數裏面的 this 是繼承外面的環境。
一個例子
let obj={ a:222, fn:function(){ setTimeout(function(){console.log(this.a)}) } }; obj.fn();//undefined |
不難發現,雖然 fn() 裏面的 this 是指向 obj ,但是,傳給 setTimeout 的是普通函數, this 指向是 window , window 下面沒有 a ,所以這裏輸出 undefined。
換成箭頭函數
let obj={ a:222, fn:function(){ setTimeout(()=>{console.log(this.a)}); } }; obj.fn();//222 |
這次輸出 222 是因為,傳給 setTimeout 的是箭頭函數,然後箭頭函數裏面沒有 this ,所以要向上層作用域查找,在這個例子上, setTimeout 的上層作用域是 fn。而 fn 裏面的 this 指向 obj ,所以 setTimeout 裏面的箭頭函數的 this ,指向 obj 。所以輸出 222 。
call和apply
call 和 apply 的作用,完全一樣,唯一的區別就是在參數上面。
call 接收的參數不固定,第一個參數是函數體內 this 的指向,第二個參數以下是依次傳入的參數。
apply接收兩個參數,第一個參數也是函數體內 this 的指向。第二個參數是一個集合對象(數組或者類數組)
let fn=function(a,b,c){ console.log(a,b,c); } let arr=[1,2,3]; |
如上面這個例子
let obj1={ a:222 }; let obj2={ a:111, fn:function(){ alert(this.a); } } obj2.fn.call(obj1); |
call 和 apply 兩個主要用途就是
1.改變 this 的指向(把 this 從 obj2 指向到 obj1 )
2.方法借用( obj1 沒有 fn ,只是借用 obj2 方法)
---------------------
原文:https://blog.csdn.net/weixin_37722222/article/details/81625826
JS this指向總結