请教大家两个小问题,分别关于 ES6 解构赋值与 TS 的类型 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
samuelclassic
V2EX    程序员

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

  •  
  •   samuelclassic 2024-03-31 19:53:52 +08:00 1961 次点击
    这是一个创建于 560 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    目前小弟呆在一家小公司,开发算上我只有两个人。我的上司,负责后端,在我眼里他技术比我好得多,会 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  
       2024-03-31 20:05:04 +08:00   6
    他写 java 写傻了,但他是你上司
    samuelclassic
        2
    samuelclassic  
    OP
       2024-03-31 20:11:06 +08:00
    @Leviathann 因为我不了解 Java ,这两天在学语法。似乎 Java 里没有解构赋值?另外因为他是我的上司,我也搜了相关问题,考虑到对方担心我离职后代码的维护工作,所以让我这样写。于是有点纠结礼拜一要不要重新跟他讨论一下。
    samuelclassic
        3
    samuelclassic  
    OP
       2024-03-31 20:13:27 +08:00
    上面举的第二个例子有误,勘正为:
    ```typescript
    class YourClass {
    // 已有的属性和方法
    // ...
    }

    interface WithLoadingStatus {
    isLoading: boolean;
    }

    type YourTypeWithLoadingStatus = YourClass & WithLoadingStatus;

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

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

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

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

    另外赞同一楼,hhh
    WasteNya
        8
    WasteNya  
       2024-04-01 05:05:03 +08:00 via Android
    https://github.com/labs42io/clean-code-typescript

    可以看看这个链接内容

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

    当然怎么使用都可以,不会有性能问题,这个完全是个人偏好。
    lolizeppelin
        11
    lolizeppelin  
       2024-04-01 10:55:05 +08:00
    我觉得我语文有问题看不懂 2333
    shunia
        12
    shunia  
       2024-04-01 11:08:40 +08:00
    写的确实有点让人看不懂

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

    第二个例子,实际情况可能过于复杂,择优使用即可,没有更加标准的做法。如果考虑长期大规模维护的话,不要在一个稳定的类型之外附加一个不稳定的临时类型。你提供的例子里的 type 合并我一般只在内部代码里使用,因为 isLoading 通常只需要在一个临时的环境下处理。写 type 或者 interface 其实就是写接口,确实可以多考虑一下。
    samuelclassic
        13
    samuelclassic  
    OP
       2024-04-01 12:03:38 +08:00 via iPhone
    感谢楼上的各位。
    ragnaroks
        14
    ragnaroks  
       2024-04-01 17:54:10 +08:00
    java 如果要传递一个对象参数,需要写一个 class ,不能直接 {}
    lizy0329
        15
    lizy0329  
       2024-04-03 15:42:45 +08:00
    必填用基础类型,选填用 object 就行
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5652 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 01:40 PVG 09:40 LAX 18:40 JFK 21:40
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86