天天看點

關于JavaScript this指向

首先處理代碼的執行(非箭頭函數)

  1. 當代碼直接執行
function a() {
	return this;
}
a() 
// 等價于 
a.call(undefined) 
// 嚴格模式 等于undefined 非嚴格模式等于window
           
  1. 當函數前有 “.”
let a = {
 	func1: function a () {
		return this
	}
}
a.func1()
// 等價于 
a.func1.call(a)
           

先上代碼

var value = 1;
var foo = {
  value: 2,
  bar1: function () {
    return this.value;
  },
  bar2: () => {
    return this.value;
  },
  bar3: () => {
    return function() {
      return this.value
    }
  },
  bar4: function() {
    return () => { return this.value}
  },
  bar5: function() {
    console.log('this', this)
    return function() {
        console.log('inner this', this)
        return this.value;
    }
  }
}
           

運作結果

foo.bar1() // === foo.bar.call(foo)  === 2
foo.bar2()
 // 等價于  foo.bar2.call(foo)  但是 箭頭函數不接受this參數, 而是使用申明時候的this ,結果是1
foo.bar3() 
// 等價于 foo.bar3.call(foo)() => foo.bar3.call().call(undefined) => 結果取 window.value => 1 ,如果嚴格模式将報錯 Cannot read property 'value' of undefine
foo.bar4()()
// 等價于 foo.bar4.call(foo)() =>  foo.bar3.call(foo).call(undefine) => 因為第二個函數是箭頭函數 是以取第一個call的入參,是以是foo.value => 2
 foo.bar5()()
 // 等價于 foo.bar.call(foo).call(undefined) => 1 嚴格模式 => Cannot read property 'value' of undefine
           

再舉一個例子

document.body.onclick = () => {
    console.log(this)
}
// this === window,因為是箭頭函數 不管怎麼調用都是window

document.body.onclick = function() {
    console.log(this)
}

// 預設情況下 點選body 相當于執行 
// document.body.onclick() ==> 
// document.body.onclick.call(body) ==> 
// this === body

// 特殊情況
const a = document.body.onclick;
a() // 等價于 a.call(undefined) => this === window => 嚴格模式等于undefined

           

繼續閱讀