• 解决结构赋值中函数的this指向问题


    概要

    我们在开发中经常使用解构赋值,这样可以使我们的代码显得更加精简,清晰,但是它同样面临this指向出错的问题。

    本文将具体指出问题所在和解决方法。

    代码及实现

    问题提出

    class Person {
        constructor(){
            this.name = "Tom";
            this.age = 12;
        }
         getPersonInfo(){
            console.log(this.name + " # " + this.age);
        } 
    }
    const { getPersonInfo } = new Person();
    getPersonInfo();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    执行结果:

    在这里插入图片描述
    getPersonInfo 方法并没有成功执行,this是undefined。

    问题原因

    事实上,解构赋值和下面的基本赋值方式是没有本质区别的,只是显得代码更加精简。

    const person = new Person();
    const getPersonInfo = person.getPersonInfo;
    
    • 1
    • 2

    所以,基本赋值方式所面临的问题,解构赋值也同样会遇到。getPersonInfo 是类内方法,如果将其脱离对象的上下文使用,则方法中的this肯定变为undefined。

    问题解决

    类中方法需要支持解构赋值,就将其定义成箭头函数

    class Person {
        constructor(){
            this.name = "Tom";
            this.age = 12;
        }
        getPersonInfo = ()=>{
            console.log(this.name + " # " + this.age);
        } 
    }
    const { getPersonInfo } = new Person();
    getPersonInfo();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    此方法虽然比较简便,但是可能存在兼容性的问题,毕竟箭头函数是ES6的语法。

    使用ES5的bind方法固定类内方法的this,无论是否需要解构赋值,都可以正常工作。

    class Person {
        constructor(){
            this.name = "Tom";
            this.age = 12;
            this.getPersonInfo = this.getPersonInfo.bind(this);
        }
         getPersonInfo(){
            console.log(this.name + " # " + this.age);
        } 
    }
    const { getPersonInfo } = new Person();
    getPersonInfo();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    用函数调用函数的方式解决上述问题

    class Person {
        constructor(){
            this.name = "Tom";
            this.age = 12;
            const { getPersonInfo } = this;
            const self = this;
            this.getPersonInfo = function(){
                getPersonInfo.call(self);
            }
        }
         getPersonInfo(){
            console.log(this.name + " # " + this.age);
        } 
    }
    const { getPersonInfo } = new Person();
    getPersonInfo();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在this失效之前,将其赋值给self。后面getPersonInfo通过call方法被调用,内部的this也就被强制成当前Person类的实例。

    使用函数调用函数的方式,除了可以解决this的问题,还可以让代码获得更高的灵活性。

    function createUUID() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
           var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
           return v.toString(16);
        });
     }
    class Person {
        constructor(idGenerator = createUUID){
            const { setPersonInfo } = this;
            const self = this;
            this.setPersonInfo = function(name,age){
                const id = idGenerator();
                setPersonInfo.apply(self, [id, name, age]);
            }
        }
         setPersonInfo(id, name, age){
            this.name = name;
            this.age = age;
            this.id = id; 
            console.log(this.id + " # " + this.name + " # " + this.age);
        } 
    }
    const { setPersonInfo } = new Person();
    setPersonInfo("Tom", 12);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    上述代码在setPersonInfo方法中,需要三个参数id,name和age,其中name和age是需要通过但是传过来,但是id需要调用GUID生成器获取,理论上id的获取过程和用户的业务逻辑无关。

    所以通过这种类似柯理化的方式,将参数切割,对外的接口中,只需要传递name和age,里面真正调用setPersonInfo方法的时候,再生成新的GUID。

  • 相关阅读:
    ESP32下的ble数据notify收发(支持ESP-IDF4.4\ESPIDF5.1)
    Linux命令-sed
    一文学会,数据库中单、双引号以及反引号的使用
    HotSpot算法细节实现——安全点
    常见数据库介绍对比之SQL关系型数据库
    Modbus转Profinet网关在金银精炼控制系统中应用案例
    运动与健康
    Java SSM Spring MVC 响应数据和结果视图+文件上传+异常处理+拦截器
    漫谈:C语言 C++ 函数返回值究竟是什么
    小功率电源自动测试系统-ate电源测试系统-led电源测试系统NSAT-8000
  • 原文地址:https://blog.csdn.net/weixin_43263355/article/details/126659962