1、全局环境下的this指向
在全局作用域下,无论是否开启严格模式 this 都指向 window。
'use strict'
console.log(this) // window
2、函数调用模式
当一个函数不是一个对象的属性被调用,而是直接作为函数来调用。
this的指向分为以下两种情况:
- 非严格模式,等价于 window 调用函数
function fun(){
console.log(this)
}
fun() //输出 window ,等价于 window.fun()
- 严格模式,严格模式下this禁止指向window
function fun(){
'use strict'
console.log(this)
}
fun() //undefined
3、方法调用模式
函数作为对象的方法来调用。this 指向调用的对象
var obj = {
a:1,
fun: function(){
console.log(this)
}
}
obj.fun() //{a: 1, fun: ƒ}
根据上面的代码衍生出了一个问题,如果是一个多层的对象,那么 this 指向谁呢?
var obj = {
a:1,
b:{
name:'b',
fun: function(){
console.log(this)
}
}
}
obj.b.fun() //{name: 'b', fun: ƒ}
根据输出结果可以得出,如果是多层的对象调用方法的话,方法中的 this 指向最近的调用对象。
4、call、apply、bind调用模式
call、apply、bind三个方法都是用来改变this的指向的。
call、apply、bind 调用模式下会将调用这三个方法的函数(即下面代码中的 fun 函数)中的 this 指向转成指向三个方法中的第一个参数(即下面代码中 obj 对象)
var obj = {
a:1
}
function fun(){
console.log(this)
}
fun() //window
fun.call(obj) // {a: 1}
fun.apply(obj) // {a: 1}
fun.bind(obj)() // {a: 1}
原本直接调用 fun 函数(即上面的函数调用模式)this 指向的是 window ,通过使用使用call、apply、bind 三个方法将 fun 函数中的 this 指向了 obj 对象。
注意: bind 是永久绑定 this 指向,当 bind 绑定 this 执行后,this 指向将不再发生改变。
5、构造器调用模式
即在构造函数中的 this 指向,构造函数的 this 指向 new 出来的实例对象。
function Student(name,age,id){
this.name = name
this.age = age
this.id = id
}
let stu1 = new Student('小明',18,'001')
console.log(stu1.name,stu1.age,stu1.id)
let stu2 = new Student('小红',18,'002')
console.log(stu2.name,stu2.age,stu2.id)
6、箭头函数中的this指向
箭头函数不同于传统 JavaScript 中的函数,箭头函数并没有属于⾃⼰的 this,它所谓的 this 是捕获其所在上下⽂的 this 值,作为⾃⼰的 this 值,并且由于没有属于⾃⼰的 this ,所以是不能被 new 调⽤的,这个所谓的 this 也不会被改变。
let fun = () => {
console.log(this)
}
fun() //window
let obj1 = {
name: 'obj1',
fun: () => {
console.log(this)
}
}
obj1.fun() //window
//上方因为对象不构成单独的作用域,所以箭头函数的this就指向了全局作用域window
let obj2 = {
name: 'obj2',
fun1: function(){
let fun2 = () => {
console.log(this)
}
fun2()
}
}
obj2.fun1() //{name: 'obj2', fun1: ƒ}
// 尝试将 obj1 内 fun 箭头函数的 this 指向 obj2
obj1.fun.call(obj2) //window ,修改 this 指向失败
7、html中元素绑定事件中的this指向
当一个元素被绑定事件处理函数时,this指向被点击的这个元素。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>html元素绑定事件的this指向问题</title>
</head>
<body>
<button onclick="fun()">点我</button>
</body>
<script>
var btn = document.querySelector('button')
btn.onclick = function fun(){
console.log(this)
}
</script>
</html>
点击按钮后输出:
注意:
当出现多种 this 调用模式同时使用时,根据优先级来判断 this 的指向,哪个调用方式的优先级高的 this 指向就遵循哪种调用模式。
优先级:构造器调用模式 > call、apply、 bind 调用模式 > 方法调用模式 > 函数调用模式