JS中的this指向問題 ๑乛◡乛๑老底都被掀出來了

this

this關鍵字,就是所謂的執行上下文。this關鍵字在函數中,表示的是一個指向,this的指向永遠是一個對象。
哪個對象調用函數,函數裏面的this指向哪個對象。

代碼示例:

function f() {
	let text="哈哈哈"
	console.log(this.text) // undefined
	console.log(this)      // Window
}
f()

上面的代碼等價於:

function f() {
	let text="哈哈哈"
	console.log(this.text) // undefined
	console.log(this)      // Window
}
window.f()

f()函數實際上是被window對象調用的

var o = {
	text:'呵呵',
	f:function(){
		console.log(this.text) // 呵呵
		console.log(this)      // {text: "呵呵", f: ƒ}
	}
}
o.f()

這裏this指向對象o,因爲是對象o調用f()
上面代碼等價於:

var o = {
	text:'呵呵',
	f:function(){
		console.log(this.text) // 呵呵
		console.log(this)      // {text: "呵呵", f: ƒ}
	}
}
window.o.f()

由此可以看出this指向的是最後調用它的對象
下面再來看看這個:

var o = {
	text:'呵呵',
	a:{
		text:'嘿嘿',
		f:function(){
			console.log(this.text)  // undefined
			console.log(this)       // Window
		}
	}
}
var fun = o.a.f
fun()

上面this指向window, 最下面的fun()等價於window.fun()。而this指向的是最後調用它的對象

function f(){
	this.text="呵呵"
}
var o = new f()
console.log(o.text) // 呵呵
console.log(o)     // f {text: "呵呵"}

上面,new關鍵字創建了一個對象實例onew關鍵字會改變this的指向,這個時候指向對象o

假如,函數裏有returnthis指向會怎樣?

function f() {
	this.text="呵呵"
	return {}
}
var o = new f
console.log(o.text) // undefined
onsole.log(o)    // {}
function f() {
	this.text="呵呵"
	return function(){};
}
var o = new f
console.log(o.text) // undefined
console.log(o)  // ƒ (){}
function f() {
	this.text="呵呵"
	return 1
}
var o = new f
console.log(o.text) // 呵呵
console.log(o)    // f {text: "呵呵"}
function f() {
	this.text="呵呵"
	return null
}
var o = new f
console.log(o.text) // 呵呵
console.log(o)    // f {text: "呵呵"}

由以上代碼可知:
如果返回值是一個對象,this指向這個返回的對象;
如果返回值不是一個對象,this還是指向函數的實例
注意: 雖然null也是對象,但它比較特殊,this指向的是函數的實例

匿名函數的this指向問題:

var o = {
	text:'呵呵',
	f:function(){
		return function(){
			console.log(this.text) // undefined
			console.log(this)      // Window
		}
	}
}
o.f()()

上面,f方法return了一個匿名函數,這個匿名函數中的this指向window

關於setIntervalsetTimeout中的this指向問題

const people = {
	name: '小白',
	sayHi() {
		// this 即當前對象
		console.log(this)
	},
	wait() {
		setTimeout(function() {
			// this === window
			console.log(this)
		})
	}
}
people.sayHi() // {name: "小白", sayHi: ƒ, wait: ƒ}
people.wait()  // Window

從上面可以看出,setTimeout中的this指向了window對象。
這是因爲setTimeout()調用的代碼運行在與所在函數完全分離的執行環境上。這會導致這些代碼中包含的 this 關鍵字會指向 window對象

箭頭函數
箭頭函數的this 是取上級作用域的值
箭頭函數的this定義:箭頭函數的this是在定義函數時綁定的,不是在執行過程中綁定的。簡單的說,函數在定義時,this就繼承了定義函數的對象。

const people = {
	name: '小白',
	sayHi() {
		// this 即當前對象
		console.log(this)
	},
	wait() {
		// 箭頭函數的this 是取上級作用域的值
		setTimeout(() => {
			// this === 即當前對象
			console.log(this)
		})
	}
}
people.sayHi() // {name: "小白", sayHi: ƒ, wait: ƒ}
people.wait()  // {name: "小白", sayHi: ƒ, wait: ƒ}

如果想改變this的指向,可以使用:call() apply() bind()

fn.call(this, p1, p2, p3)
fn.apply(this, arguments)
var fn1 = fn.bind(this, p1, p2, p3)
fn1()

相同點:

  • 改變對象的執行上下文(總的來說,就是改變this的指向)
  • 都可以指定調用實參。

不同點:

  • call()bind()的參數是直接連續傳遞,而apply傳遞參數是以一個數組傳遞
  • bind()會返回一個方法。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章