ES6箭頭函數(shù)this和普通函數(shù)中的this

原文鏈接:http://www.itdecent.cn/p/c1ee12a328d2

常見(jiàn)的window屬性和方法有alter,document,parseInt,setTimeout,setInterval,localtion等等,這些在默認(rèn)的情況下是省略了window前綴的。(window.alter = alter),所以下文提到箭頭函數(shù)解決了匿名函數(shù)this指向的問(wèn)題(匿名函數(shù)的執(zhí)行環(huán)境具有全局性),包括setTimeout和setInterval中使用this所造成的問(wèn)題。

以下都是在非嚴(yán)格模式下討論
1.普通函數(shù)中的this
在JavaScript中,this是在函數(shù)執(zhí)行過(guò)程中自動(dòng)生成的一個(gè)內(nèi)部對(duì)象,指的就是當(dāng)前對(duì)象。
js的函數(shù)可以多層嵌套,如果內(nèi)層的想要獲得外層的this,可以定義一個(gè)變量?jī)?chǔ)存起來(lái)
var _this=this
在全局函數(shù)中,比如匿名函數(shù),this指向的是window。
例子:

var name=" the window";
var obj = {
    name:'my obj',
    getNameFun:function(){
        return function(){
            return this.name;
        }
    }
}
console.log(obj.getNameFun()());// the window

原因是,匿名函數(shù)的執(zhí)行環(huán)境是全局的,而且this只在函數(shù)內(nèi)部起作用。此時(shí)的this.name在匿名函數(shù)中找不到,所以就從全局中找,找到后打印出來(lái)。

上面的例子改寫(xiě)一下

var name=" the window";
var obj = {
    name:'my obj',
    getNameFun:function(){
        var _this=this
        return function(){
            return _this.name;
        }
    }
}
console.log(obj.getNameFun()());//my obj

在getNameFun內(nèi)將this賦給_this,此時(shí)的_this指向的是掛載(調(diào)用)的對(duì)象,即為obj,在匿名函數(shù)中調(diào)用_this.name會(huì)在obj上查找相應(yīng)的數(shù)據(jù),就不會(huì)在全局上查找

函數(shù)的執(zhí)行對(duì)象放在window

function test(){
    console.log(this);
}
test();//window

問(wèn)題:為啥是window,因?yàn)闆](méi)變量聲明?

關(guān)于setTimeout和setInterval的this指向問(wèn)題

var obj = {
  func:function(){
    console.log(this);
  },
  say:function(){
    var that = this;
    setTimeout(function(){
      console.log(that)
    });
  }
}
obj.func();//obj
obj.say();//obj

把 var that = this;去掉

var obj = {
  func:function(){
    console.log(this);
  },
  say:function(){
    setTimeout(function(){
      console.log(that)
    });
  }
}
obj.func();//obj
obj.say();//window

問(wèn)題: setTimeout里執(zhí)行的函數(shù)為啥是window,因?yàn)閟etTimeout就是window下的方法
例子:

window.val = 1;
var obj = {
  val:2,
  dbl:function(){
    this.val*=2;
    val*=2;
    console.log(this.val);
    console.log(val);
  }
}
obj.dbl();//4 2
var func = obj.dbl;
func();//8 8

執(zhí)行obj.dbl()時(shí),this.val的this指向obj內(nèi)的val=2;val在obj內(nèi)沒(méi)有定義所以從全局上找val=1,因此運(yùn)算結(jié)果為4 2
func的執(zhí)行對(duì)象是window,我們可以此時(shí)全局的val已經(jīng)等于4了,在經(jīng)過(guò)this.val=2,val=2的運(yùn)算,打印的結(jié)果就是8 8。
問(wèn)題:為啥執(zhí)行func,全局的val等于4,不是2?

2.ES6箭頭函數(shù)this

箭頭函數(shù)的this定義:箭頭函數(shù)的this是在定義函數(shù)時(shí)綁定的,不是在執(zhí)行過(guò)程中綁定的。簡(jiǎn)單的說(shuō),函數(shù)在定義時(shí),this就繼承了定義函數(shù)的對(duì)象。
所以,這會(huì)很好的解決匿名函數(shù)和setTimeout和setInterval的this指向問(wèn)題。不用再去給其變量存儲(chǔ)this。

var obj = {
  func:function(){
    console.log(this);
  },
  say:function(){
    setTimeout(()=>{
      console.log(this)
    });
  }
}
obj.func();//obj
obj.say();//obj
var a=1;
function test(){
    console.log(this.a);
    console.log(this);
    this.a=2;
    return ()=>{console.log(this.a);console.log(this);}
}
var x=new test()();
//undefined
//test {}
//2
//test {a: 2}

注:new test()(),第一個(gè)括號(hào)是返回匿名函數(shù),第二個(gè)括號(hào)是執(zhí)行返回的匿名函數(shù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容