JavaScript中this常見的兩個坑
JavaScript中的this就像魔法一樣,稍有不慎就會走火入魔.......
正確理解this,得從一個概念「執行上下文」 談起!
何謂執行上下文(Execution Context)?
JavaScript解釋器使用執行上下文的概念,執行上下文可以理解為一種「環境」。腳本中每條語句在執行時,其執行上下文都會是以下三種之一:
全局上下文
腳本中(非函數中)的代碼的執行上下文屬於全局上下文。注意在Web開發中每個頁面只有一個全局上下文,在作用域上對應全局作用域。
函數上下文
在函數中的運行的代碼,每個函數都擁有自己的函數上下文。在作用域上對應函數級作用域
eval上下文(隱身的)
在名為Eval()的內部函數中作為代碼執行的文本
在JavaScirpt中,this正是指向當前函數中下在執行的上下文環境,總結起來JavaScript有四種不同的函數調用類型:
函數調用 alert("請關注")
方法調用 console.log("教授學苑")
構造函數調用 new RegExp("帶給你快樂的")
間接調用 alert.call(undefined, "開發知識")
在以上每一項調用中,它都會擁有各自獨立的上下文環境,就會造成this所指向意義有所差別。此外,嚴格模式也會對執行環境造成影響。
坑1 :內部函數中的this指向哪裡?
正確輸出為:
true
false
NaN
numbers.sum()是一個對象方法調用,故sum的上下文是numbers對象。雖然calculate定義在sum函數內,但不能以為在calculate內this也指向的是numbers。calculate()是一個函數調用(不是方法調用哦!),所以函數調用中的this指向的是全局對象。
使用.call()方法修改執行上下文。
坑2:方法會分離它自身的對象
輸出結果:
why?
方法調用如果不依靠對象,那麼就是一個函數調用!上面的例子中myCat.logInfo方法被分離出來作為參數傳入函數內setTimeout(mycat.logInfo)。當logInfo被作為函數調用時,this 已經指向了全局對象。
可以使用.bind()方法綁定被分離的對象,解決上下文問題!
關注「教授學苑」,期待帶給你快樂的開發知識!
![](https://pic.pimg.tw/zzuyanan/1488615166-1259157397.png)
![](https://pic.pimg.tw/zzuyanan/1482887990-2595557020.jpg)
※Google Guava 筆記(一)-Collections
※Google Guava 筆記(二)-深入探索
※JavaScript 代碼規範,自帶 linter & 代碼自動修正
※JavaScript 之Array 你真的了解嗎?
TAG:教授學苑 |