javascript 高级编程 this指向问题【1】

本文详细探讨了JavaScript中this关键字的行为,包括全局作用域、普通函数、定时器、对象方法、构造函数、箭头函数以及特殊场景下的this指向。通过实例和call、apply、bind的使用,帮助读者掌握this的动态性和箭头函数的独特性。
摘要由CSDN通过智能技术生成

目录

1. 直接打印一个this

2.普通函数的打印this

3. 定时器内部打印this

4. 对象打印this

5. 按钮点击事件打印this

6. 构造函数里面的this指向


总结:

        总结:
        1. 全局中,打印this 指向window
        2. 全局中,函数方法全局调用 this指向window
        3. class类方法中,调用 this指向实例化的类
        4. call bind apply方法绑定调用函数时,this指向被传入的对象,
           同时还可以传入参数。
           call可以传入一个或者多个参数,
           call调用的时候就执行,无需手动调用
           bind可以传入一个或者多个参数,但必须手动调用
           apply和call的区别就是,传入的参数必须是数组 不然就报错
        5. 构造函数中,的this指向 new出来的实例
        6. 前面四种this都是动态的,调用时才确定的。
           箭头函数中this 指向父级的上下文中的this,是定义的时候就确定的。


        ---------------追问时补充
        1. 为什么需要this?
           语言的运行需要环境
           环境 =》JS环境分为web浏览器和node环境
           为什么需要环境?
           函数可以在不同的运行环境执行,JS也允许当前函数体内部使用运行环境的其它变量,因此需要this指明代码到底在哪里执行。


        1. 全局时,严格模式下,默认绑定全局是不合法的,this被置为undefined
        2. 对象实例 调用对象里面的方法 记住原则 打印的是最后调用的对象
        3. 构造函数中的this指向新对象的实例 是因为内部使用了new方法call 指向了新创建的对象
           new一个构造函数的过程:
           简单版本:
                 1. 创建一个新对象 新的内存空间
                 2. this指向这个对象空间 通过call办法
                 3. 执行构造函数里面的方法 给新的对象赋值
                 4. 返回这个实例对象

        4. 类注意事项
        如果类实例对象的方法存储 稍后调用会失去追踪 this指向undefiend
        因此需要将bind方法指回实例对象

1. 直接打印一个this

        // 1. 直接打印this
        console.log(this); // // Window

2.普通函数的打印this

指向window

        // 2. 直接调用函数
        function fun() {
            console.log(this);
        }
        fun(); // Window

 3. 对象打印this

发现打印的是调用的对象本身

        var obj = {
            name: 'xxx',
            star: function () {
                console.log(this);
            }
        }

4. call apply bind都可以改变this指向

        let prox1 = {
            name: 'jmq'
        }
        let prox = {
            name: 'lzh',
            age: 18,
            sayhello: function() {
                console.log(this);
            }
        }
        prox.sayhello()
        prox.sayhello.call(prox1) // prox1
        prox.sayhello.apply(prox1) // prox1
        prox.sayhello.bind(prox1)() // prox1
        // 不同点是bind需要手动调用

5. class类中 this指向new后的实例对象

           class Person {
            constructor(name, age) {
                this.name = name;
                this.age = age
            }
            sayhello() {
                console.log(this); // 指向new之后的实例对象
            }
        }
        const person1 = new Person('lzh', 19)
        person1.sayhello()
        // 5.1 类使用的注意情况 如果把方法存起来 会失去追踪 需要手动bind解决这个问题
        const say = person1.sayhello
        say() // undefined 
        const say2 = person1.sayhello.bind(person1)
        say2() // 成功指回去

 6. 箭头函数

        let obj2 = {age: '123'}
        var name = '杨志'
        let pox = {
            name: '小红',
            run: () => {
                console.log(this);
            }
        }
        pox.run()
        // 箭头函数的this指向父级的上下文对象 
        // 不可以被call apply bind改变

7. 特殊情况1

        const zhangsan = {
            name: '张三',
            sayHi() {
                console.log(this);
            },
            wait() {
                setTimeout(function() {
                    console.log(this); // 指向window
                })
            }
        }
        zhangsan.sayHi() // zhangsan对象
        zhangsan.wait() // window

        // 定时器内部打印this
        let timer = setTimeout(() => {
            console.log(this); // window
        }, 1000)

7. 特殊情况2

        const zhangsan2 = {
            name: '张三',
            sayHi() {
                console.log(this);
            },
            waitAgain() {
                setTimeout(() => {
                    // this指向 当前对象
                    console.log(this);
                })
            }
        }
        zhangsan2.waitAgain()
        // 箭头函数 this指向 当前函数所在父级的上下文对象 
        // 当前函数的父级是waitAgain函数 上下文是在zhangsan2这个对象

8. 按钮点击事件打印this

打印的是按钮本身。为什么?

因为是点击按钮而触发的点击事件,this指向按钮

        // 5. 按钮点击事件
        btn.addEventListener("click", function () {
            console.log(this); // button这个按钮这个元素
        })

本文章参考了:

一图搞懂javascript中的this与call/apply/bind的6中关系_田兴的博客-CSDN博客

关于call和apply和bind的用法可以查看:

「干货」细说 call、apply 以及 bind 的区别和用法 - 掘金

我的下面这篇文章有具体的习题

JavaScript 高级编程,this指向问题【2】_hangshao_123的博客-CSDN博客

结尾:

学习id: 201903090124-28

现在是大三学生,学习到了前后端交互阶段,如有不对的地方,欢迎指正,一起努力呀。如有转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值