this指向是工作和麵試中經常會遇到的問題。
根據個人理解,簡單從3個方面來總結一下this的指向問題。
1. 若是全域性函數,並且沒有直接呼叫它的物件,沒有嚴格模式,則預設指向全域性window
或global
2. 若是全域性函數,並且沒有直接呼叫的物件,嚴格模式下,this
指向undefined
3. 箭頭函數的this
,是在函數定義時根據上下文函數決定的。若是全域性定義,則this
指向window
或global
。若上下文有函數環境,則指向該上下文的this
4. 使用call
改變this
的指向取決於call
的第一個引數,若第一個引數是null
,還是會綁在全域性的
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