Bootstrap

JS 关于 this 指向的几种情况

一、this 指向 window

1、全局函数里面的 this 指向 window
2、箭头函数里面的 this 指向 window

// 定义全局变量 title 与函数 foo
var title = 'hello,world' // 注意:若使用 let 定义则不属于全局变量
function foo() {
	console.log(this.title)
}

function arrow() {
	let title = 'hello,arrow'
	return () => {
		return () => {
			console.log(this.title)
		}
	}
}
foo() // 输出 hello,world 证明第 1 点
arrow()()() // 输出 hello,world 证明第 2 点

3、事件绑定函数里面的 this 默认指向 window

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <button id="button" onclick="onTouchMe()">点我</button>
  <script type="text/javascript">
  	var title = 'hello,world'
  	function onTouchMe() {
		console.log(this.title) // 输出'hello,world' 证明第 3 点
	}
  </script>
</body>
</html>

二、this 指向自身函数(对象)

1、new Foo().getTitle() 里面的 this 指向当前自身 Foo 构造函数
2、obj.getTitle() 里面的 this 指向自身 obj 对象
以上两点可理解为:谁调用我,this 环境就属于谁。

class Foo{
	constructor(title) {
		this.title = title
	}
	getTitle() {
		console.log(this.title)
	}
}
// 输出 Hello,world / Hello,Tony 证明第 1 点
const f1 = new Foo('Hello,world')
const f2 = new Foo('Hello,Tony')
f1.getTitle()
f2.getTitle()

// 输出 hello,obj 证明第 2 点
let obj = {
	title: 'Hello,obj',
	getTitle() {
		console.log(this.title)
	}
}
obj.getTitle()

三、this 指向 undefined

1、严格模式下,this 指向 undefined

"use strict"
function getThis() {
	console.log(this)
}
getThis() // 输出 undefined 证明 第 1 点

四、setTimeout 里面的 this

1、普通函数 this 指向 window
2、箭头函数的 this 指向上一层环境

var title = 'hello,world'
let obj = {
	title: 'hello,obj',
	getTitle() {
		setTimeout(function() {
			console.log(this.title)
		})
	}
}
obj.getTitle() // 输出 hello,world  证明第 1 点


var title = 'hello,world'
let obj = {
	title: 'hello,obj',
	getTitle() {
		//  此时里面的 console.log(this.title) 就相当于在这里访问
		// console.log(this.title)
		setTimeout(() => {
			console.log(this.title)
		})
	}
}
obj.getTitle() // 输出 hello,obj 证明第 2 点

五、dom 事件绑定里面的 this

1、事件绑定里的 this 指向随着函数绑定环境而变,默认是 window

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <button id="button" onclick="onTouchMe()">点我</button>
  <script type="text/javascript">
  	var title = 'hello,world'
  	// 默认是 window
  	function onTouchMe() {
		console.log(this.title) // 输出'hello,world' 
	}
	// ============================================
	let obj = {
		title: 'hello,obj',
		onTouchMe() {
			console.log(this.title) // 输出 hello,obj' 
		}
	}
	// 随函数绑定环境而变
	document.getElementById('button').onclick = obj.onTouchMe
  </script>
</body>
</html>

六、改变 this 指向的三个方法:apply / call / bind

1、apply / call / bind

let a = {
	title: 'Hello,world',
	getTitle() {
		console.log(this.title)
	}
}
let b = {
	title: 'Hello,Tony'
}
a.getTitle() // 正常输出 Hello,world
a.getTitle.apply(b, ['参数1', '参数2']) // 将 this 环境指向 b ,输出 Hello,Tony
a.getTitle.call(b, '参数1', '参数2') // 将 this 环境指向 b ,输出 Hello,Tony
a.getTitle.bind(b)('参数1', '参数2') // 将 this 环境指向 b ,输出 Hello,Tony

// 注意:bind 不能多次指向,因为第一次绑定时环境就已经确认好了。
a.getTitle.bind(b).bind(a)() //  this 环境依然属于 b

好了,本文就到这里,希望本文的 this 情况对你有帮助。

;