V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
Stefango
V2EX  ›  JavaScript

.map(window.open) 和 .map((one)=>window.open(one)) 的区别是啥?

  •  
  •   Stefango · 2022-04-06 18:32:59 +08:00 · 2327 次点击
    这是一个创建于 723 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这两行代码的执行结果咋不一样(一个打开新窗口,一个在当前窗口打开新标签页)? this 不同?

    `https://baidu.com
    https://163.com`.split(/\r|\n/ig).map(window.open)
    
    
    `https://baidu.com
    https://163.com`.split(/\r|\n/ig).map((one)=>window.open(one))
    
    16 条回复    2022-04-08 09:50:24 +08:00
    wiluxy
        1
    wiluxy  
       2022-04-06 18:40:10 +08:00   ❤️ 4
    map 的回调函数会传入三个值 item,index,arr ,window.open 的参数也不止一个,第一种写法相当于是把他们三个值都传到了 window.open 里面,第二种是显式指定了只传第一个参数
    Stefango
        2
    Stefango  
    OP
       2022-04-06 18:56:35 +08:00   ❤️ 1
    @wiluxy 对的!
    SorcererXW
        3
    SorcererXW  
       2022-04-06 18:56:53 +08:00
    后者更保险
    noe132
        4
    noe132  
       2022-04-06 18:58:34 +08:00
    interface Array<T> {
    map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
    }
    interface Window {
    open(url?: string | URL, target?: string, features?: string): WindowProxy | null;
    }

    这种问题还有另外一个常见的地方就是 map to parseInt
    ["20", "20", "20", "20", "20", "20", "20"].map(parseInt)
    // [20, NaN, NaN, 6, 8, 10, 12]
    FP 中完美的 Functor.map 只需要一个参数 v 就可以了,所以很多 fp 的轮子会专门有只有一个参数版本的 map 。
    noe132
        5
    noe132  
       2022-04-06 19:02:44 +08:00
    还有一个概念在 FP 中很常见叫做 Partial Application ,其实就是让多参数函数固定住几个参数。但通常是从左边开始。像这里这种我们也可以称作 Partial Application ,只不过没那么 FP 了。

    const open = v => window.open(v)
    arr.map(open)
    就类似于把后 2 个参数固定成了 undefined
    sudoy
        6
    sudoy  
       2022-04-06 19:11:08 +08:00 via iPhone
    一楼正解
    YuTengjing
        7
    YuTengjing  
       2022-04-06 19:26:41 +08:00
    第二种方式完全是多余操作
    autoxbc
        8
    autoxbc  
       2022-04-06 20:12:41 +08:00
    个人踩坑经验,除非 map 里的函数是你自己创建的,不然永远不要用第一种写法
    SoloCompany
        9
    SoloCompany  
       2022-04-06 20:42:08 +08:00
    mxT52CRuqR6o5
        10
    mxT52CRuqR6o5  
       2022-04-06 20:45:48 +08:00
    @YuTengjing 1#说的那么清楚还多余,执行结果都不符合预期了
    YuTengjing
        11
    YuTengjing  
       2022-04-06 23:24:02 +08:00
    @mxT52CRuqR6o5 #10 你真的看懂了吗?还结果不符合预期,你拷到 chrome 里面跑一下都不会吗?
    YuTengjing
        12
    YuTengjing  
       2022-04-06 23:29:53 +08:00
    @mxT52CRuqR6o5 #10 Sorry, 逻辑确实不一样,不过我这边跑了一下,效果都是直接打开一个百度的窗口
    shintendo
        13
    shintendo  
       2022-04-07 10:30:44 +08:00
    常见的两个坑:
    1 .map(parseInt)
    parseInt 有可选的第二个参数(进制)
    2 Vue 写事件绑定 @click="getList"
    getList 如果有可选参数(页码),这个参数会接收到$event
    iqoo
        14
    iqoo  
       2022-04-07 10:52:13 +08:00
    用 typescript 第一种写法根本就过不了编译
    ragnaroks
        15
    ragnaroks  
       2022-04-07 13:13:49 +08:00
    我想到 dotnet framework 的大坑了,以前因为这个导致过几个订单数据对不上的生产事故

    method (Enumerable<T> list)

    method (T[] list)

    method (T v1,T v2)
    LeegoYih
        16
    LeegoYih  
       2022-04-08 09:50:24 +08:00
    map 的参数是方法的引用,简单的说就是 map 需要传入一个方法。
    map((one)=>window.open(one)),实际上是传了个匿名函数,匿名函数也称 lambda 表达式。

    第一种方法等价于 map((a,b,c)=>window.open(a,b,c)),TS 编译不通过因为 map 需要函数的出入参类型与 window.open 提供的不匹配,实际上静态语言都如此。JS 中这 2 种都能用是因为它不校验出入参类型和参数数量。

    PS:这里应该用 forEach ,map 不太合适
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2837 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 13:41 · PVG 21:41 · LAX 06:41 · JFK 09:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.