this指向是工做和麪試中常常會遇到的問題。面試
根據我的理解,簡單從3個方面來總結一下this的指向問題。函數
1. 如果全局函數,而且沒有直接調用它的對象,沒有嚴格模式,則默認指向全局window
或global
2. 如果全局函數,而且沒有直接調用的對象,嚴格模式下,this
指向undefined
3. 箭頭函數的this
,是在函數定義時根據上下文函數決定的。如果全局定義,則this
指向window
或global
。若上下文有函數環境,則指向該上下文的this
4. 使用call
改變this
的指向取決於call
的第一個參數,若第一個參數是null
,仍是會綁在全局的
this
指向結合下面的示例加深理解。this
(1) 如果全局函數,而且沒有直接調用它的對象,沒有嚴格模式,則默認指向全局
window
function hello1(){ console.log('我是hello1 this:',this) // window } hello1()
(2)如果全局函數,而且沒有直接調用的對象,嚴格模式下,this
指向undefined
function hello2(){ 'use strike'; console.log('我是hello2 this:',this) // undefined } hello2()
(3)用obj
直接調用hello3
函數,則第一個this
指向obj
。
setTimeOut
裏面的箭頭函數,this
指向obj
。
setTimeOut
裏面的匿名函數,this
指向window
。
由於:箭頭函數的this,是在定義箭頭函數時根據上下文函數環境決定,該箭頭函數定義在函數內部,上下文執行環境在hellow3函數內,因此指向hello3的this
var obj = { name:'aaa', hello3(){ console.log('我是hello3 this:',this); // obj setTimeout(()=>{ console.log('我是hello3 裏面箭頭函數settimeout this:',this); // obj },3000) setTimeout(function (param) { console.log('我是hello3 裏面匿名函數settimeout this:',this); // window },2000) } } obj.hello3()
(4)hello4
是普通函數,直接被obj
調用,則this
執行obj
。hello5
是箭頭函數,this
應該指向上限文函數中的this
,這裏上下文沒有函數對象,因此默認爲window
var obj2 = { name:'aaa', hello4(){ console.log('我是hello4 this:',this); // obj }, hello5:()=>{ console.log('我是hello5 this:',this); // window }, } obj2.hello4(); obj2.hello5();
(5)使用call
綁定this
,取決於call
的第一個參數,若第一個參數是null
,仍是會綁在全局的。
function foo(){ console.log(this) } foo(); // global foo.call(1); // [Number: 1] foo.call({a:10},1); // { a: 10 } 1. foo.call(null,1); // global