V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
samuelclassic
V2EX  ›  程序员

请教大家两个小问题,分别关于 ES6 解构赋值与 TS 的类型

  •  
  •   samuelclassic · 58 天前 · 1316 次点击
    这是一个创建于 58 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    目前小弟呆在一家小公司,开发算上我只有两个人。我的上司,负责后端,在我眼里他技术比我好得多,会 Java 、Python 、JS ...我写前端,后端会一些 Node 、Python 。

    事情是这样的,有一次提完 PR ,上司 review 我代码的时候跟我说,方法传参用基本类型,别用对象。以及对象的状态属性别挂载在对象上,不需要接口或者类类型来约束。

    举例

    • 对象传参,解构赋值
    // 使用基本类型传递多个参数的方式
    function printUserInfo(name, age, country) {
        console.log(`Name: ${name}`);
        console.log(`Age: ${age}`);
        console.log(`Country: ${country}`);
    }
    
    // 调用函数时直接传递多个基本类型参数
    printUserInfo('John', 30, 'USA');
    
    // 使用对象解构赋值传递多个参数的方式
    function printUserInfo({ name, age, country }) {
        console.log(`Name: ${name}`);
        console.log(`Age: ${age}`);
        console.log(`Country: ${country}`);
    }
    
    // 调用函数时传递一个包含多个参数的对象
    const user = {
        name: 'John',
        age: 30,
        country: 'USA'
    };
    
    printUserInfo(user);
    
    • 类型约束对象

    数组成员之前用了 YourClass 类作为类型,现在需要新增表示加载状态的属性。

    class YourClass {
        // 类的属性和方法
    }
    
    interface WithLoadingStatus {
        isLoading: boolean;
    }
    
    type YourTypeWithLoadingStatus = YourClass | WithLoadingStatus;
    
    const array: YourTypeWithLoadingStatus[] = [
        new YourClass(),
        { isLoading: true },
        { isLoading: false }
    ];
    

    观点

    针对第一点,我理解的是,少量参数传参用基本类型,多个用对象。上司的意思大概是,以前栈空间小,会用到对象。其次,对象参数假设在方法内被修改会改变原对象。对方的意思我理解,引用类型作为参数传递的是指针,但是解构赋值相当于声明了局部变量,除了性能上会有额外开销,似乎并不会影响原对象。假设我需要在原有方法上新增参数,使用对象参数可以不用考虑传参顺序。用基本类型的话,调用方法的时候,有些默认参数需要显式的写上去。

    针对第二点,上司觉得和 UI 相关的属性不应该写在类类型里,让我了解面向接口编程。看完之后我的理解是,TS 中接口是对对象属性进行约束,面向接口编程中的接口更多的是描述行为方法(实现多继承等),这两者似乎不能等价。

    诉求

    因为我思维比较发散,跟人沟通容易跳跃。最近忙完手头的开发事务又想起这件事情,也许上次并没有沟通明白。请大家说说自己的看法或建议,谢谢!

    15 条回复    2024-04-03 15:42:45 +08:00
    Leviathann
        1
    Leviathann  
       58 天前   ❤️ 6
    他写 java 写傻了,但他是你上司
    samuelclassic
        2
    samuelclassic  
    OP
       58 天前
    @Leviathann 因为我不了解 Java ,这两天在学语法。似乎 Java 里没有解构赋值?另外因为他是我的上司,我也搜了相关问题,考虑到对方担心我离职后代码的维护工作,所以让我这样写。于是有点纠结礼拜一要不要重新跟他讨论一下。
    samuelclassic
        3
    samuelclassic  
    OP
       58 天前
    上面举的第二个例子有误,勘正为:
    ```typescript
    class YourClass {
    // 已有的属性和方法
    // ...
    }

    interface WithLoadingStatus {
    isLoading: boolean;
    }

    type YourTypeWithLoadingStatus = YourClass & WithLoadingStatus;

    const array: YourTypeWithLoadingStatus[] = [
    { /* 已有的属性 */, isLoading: true },
    { /* 已有的属性 */, isLoading: false }
    ];
    ```
    yiranyibaozha
        4
    yiranyibaozha  
       58 天前
    @samuelclassic 看平时关系吧,如果工作之余两人也沟通得比较多,关系也还不错的话可以以日常闲聊的方式简单讨论下。否则讨论个鸡毛啊,提都别提这个事情了。

    要么就虚心接受,坚决不改🤷‍♂️。如果他再次强调这个问题你就找机会一起讨论下,再次讨论无果的话,你就按照他说的方式改呗,又不是什么大问题。

    不过我个人还是比较认同你的这个写法,本来也没什么问题,leader 非要 review 挑点毛病也没什么意思。
    samuelclassic
        5
    samuelclassic  
    OP
       58 天前 via iPhone
    @yiranyibaozha 谢谢,我还是决定不继续探讨了。回想入职初衷,上司说我可以学很多知识,我把该学的学好就很好了。
    Track13
        6
    Track13  
       58 天前
    1.除非只有一个参数,不然我都对象传过去。(有 ts 还好一点,不过对象传至少一眼能看出传的是什么)
    2.没看懂你意思。
    Rache1
        7
    Rache1  
       58 天前
    我都不敢想,如果一个方法的默认参数多了,只需要最后面几个参数的时候,需要写多少样板代码。

    当然,对于 Java 来说,那应该还有其他的方法,比如再写个 Builder 或者单独创建一个 Class 来做这个事情了

    另外赞同一楼,hhh
    WasteNya
        8
    WasteNya  
       58 天前 via Android
    https://github.com/labs42io/clean-code-typescript

    可以看看这个链接内容

    第一个举例,前端这块你的更好
    第二个举例,只要不是特别重的 Class ,怎么方便怎么来
    harrozze
        9
    harrozze  
       58 天前
    @samuelclassic “这份工作你可以学很多知识”这种是招人时候的套话,听听就行了。。。
    Belmode
        10
    Belmode  
       58 天前
    如果参数较少,直接传递,更方便;如果参数较多,解构传递会更清晰和可维护更好。

    当然怎么使用都可以,不会有性能问题,这个完全是个人偏好。
    lolizeppelin
        11
    lolizeppelin  
       58 天前
    我觉得我语文有问题看不懂 2333
    shunia
        12
    shunia  
       58 天前
    写的确实有点让人看不懂

    第一个例子,建议是必须参数尽量解开,可选参数允许使用对象,大概是这个意思:(name, age, country, options?) => any ,最大的好处是强制的 signature 约束,在 api 调整的时候能强制调用端同步,另外语义也更清晰。这个思考的点其实是你要把最终的代码当成 javascript 而非 typescript 去理解。我遇到过项目代码里面就因为全写 object ,然后日积月累的就有些地方把 object 里的字段弄混了的(参数类型最终写成了 any )。

    第二个例子,实际情况可能过于复杂,择优使用即可,没有更加标准的做法。如果考虑长期大规模维护的话,不要在一个稳定的类型之外附加一个不稳定的临时类型。你提供的例子里的 type 合并我一般只在内部代码里使用,因为 isLoading 通常只需要在一个临时的环境下处理。写 type 或者 interface 其实就是写接口,确实可以多考虑一下。
    samuelclassic
        13
    samuelclassic  
    OP
       58 天前 via iPhone
    感谢楼上的各位。
    ragnaroks
        14
    ragnaroks  
       57 天前
    java 如果要传递一个对象参数,需要写一个 class ,不能直接 {}
    lizy0329
        15
    lizy0329  
       56 天前
    必填用基础类型,选填用 object 就行
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5066 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 08:10 · PVG 16:10 · LAX 01:10 · JFK 04:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.