深入浅出 js 中 this 的指向问题

1、全局环境下的this指向

在全局作用域下,无论是否开启严格模式 this 都指向 window

'use strict'

console.log(this) // window

2、函数调用模式

当一个函数不是一个对象的属性被调用,而是直接作为函数来调用。

this的指向分为以下两种情况:

  1. 非严格模式,等价于 window 调用函数
function fun(){
    console.log(this)
}

fun() //输出 window ,等价于 window.fun()
  1. 严格模式,严格模式下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 调用模式 > 方法调用模式 > 函数调用模式

👇觉得有帮助的朋友可以支持下作者哦,您的鼓励是我创作的最大动力,如有开发问题可联系作者
请添加图片描述

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值