JavaScript中 this的指向取決於function被誰調用,而不取決於其定義。
function fn() { console.log(this) } fn()
上例中,fn是被全局對象調用,因此this指向全局對象。node
const obj = { foo: function () { console.log(this) } } let fn = obj.foo fn() obj.foo()
上例中,fn方法指向obj.foo,因爲fn方法被全局對象調用,所以this指向全局對象。而直接調用obj.foo()
,此時foo方法被obj調用,所以this指向obj。瀏覽器
function Foo() { console.log(this) } const f = new Foo()
上例中,Function Foo被看成構造函數進行了實力化,此時this指向實力化對象f。
ES2015中的class關鍵字是一種語法糖,其本質仍是聲明一個構造函數,所以其內部this指向可參考構造函數。app
function foo() { return () => { console.log(this) } } foo()()
箭頭函數雖然也是一種函數,可是其不改變內部this指向,也就是說在查找箭頭函數內部this指向時,查找的依然是包裹它的function的調用者。在上例中,foo函數返回的函數是被全局對象調用,所以this指向全局對象。函數
基於上面的四個例子,能夠總結出在JavaScript中查找this的步驟爲:this
foo()
, this指向全局對象。foo.bar()
,this指向最終調用這個方法的對象。new Person
,this指向新生成的實力化對象。fn.call, fn.apply, fn.bind
,此時this指向調用時傳入的參數。在上面提到不少次this指向全局對象,那這個全局對象究竟是什麼?命令行
若是在命令行中經過node *.js 執行時,分爲下面兩種狀況。code
if (true) { console.log(this) } console.log(this) // true console.log(this === module.exports)
在上例中,this指向{}。
由於nodejs爲保證文件的模塊做用域,在執行文件代碼時,會爲全部的文件代碼添加一個包裹函數,上面的執行相似於:對象
// exports 指向module.exports function wrapped(exports) { if (true) { console.log(this) } console.log(this) } wrapped()
所以this會指向{}。ip
function fn() { console.log(this) } fn()
在上例中,fn是全局對象調用,而node環境中,全局對象是Global,所以this指向Global。作用域