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()会返回一个方法。

在这里插入图片描述

发布了75 篇原创文章 · 获赞 381 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/weixin_40693643/article/details/104830773