首先,明確幾個基本概念
- 嚴格模式和非嚴格模式,即是否添加'use strict'; this的行為結果不同,本文只討論嚴格模式
let f=function(){
console.log(this);
}
f();
#嚴格模式下this為undefined,非嚴格模式為global對象
- 全局this在瀏覽器中指向window對象,在node中指向空對象,可以用如下代碼測試
'use strict';
console.log(this);
- this一般存在于函數(shù)內(nèi)部
- this為函數(shù)調用時所在對象的引用
let f=function () {
console.log(this);
};
let o={
name:'frank',
f:f
};
o.f();
#result
{ name: 'frank', f: [Function: f] }
- this指向的對象可以通過apply或call變更
let f=function (a,b) {
console.log(this);
};
let o={
name:'frank'
};
f.apply(o,[1,2]);
f.call(o,1,2);
#result
{ name: 'frank' }
{ name: 'frank' }
- Function.prototype.bind接收一個對象,并返回一個調用函數(shù)的拷貝,新函數(shù)的this指向該對象,在React中處理事件回調需要將bind綁定為組件對象,這樣才可以調用this.setState方法
let f=function (a,b) {
console.log(this);
};
let o={
name:'frank'
};
let f1=f.bind(o);
f1();
#result
{ name: 'frank' }
- ES6箭頭函數(shù)會自動傳遞this,而不改變this原來指向的對象,將4中的函數(shù)改為箭頭函數(shù),在React中也可以用箭頭函數(shù)來避免使用bind
let f=()=>{
console.log(this);
};
let o={
name:'frank',
f:f
};
o.f();
#result,在node中運行,this默認指向{}
{}
#多層傳遞
let f=()=>{
console.log(this);
return ()=>{
console.log(this);
};
};
let o={
name:'frank',
f:f
};
o.f()();
#result
{}
{}
#改變默認this指向對象,并向下傳遞
let f=function(){
console.log(this);
return ()=>{
console.log(this);
};
};
let o={
name:'frank',
f:f
};
o.f()();
#result
{ name: 'frank', f: [Function: f] }
{ name: 'frank', f: [Function: f] }