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

请教一个 js 箭头函数的基础问题

  •  
  •   volvo007 2021-02-03 01:19:07 +08:00 3947 次点击
    这是一个创建于 1747 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本意是想做一个判断,如果 this.goodId == 1,那么就获得一个 'a.json' 的本地 url 字符串;如果 this.goodId 是别的值,那么就拿别的字符串。

    现在的问题是,这么写:

    var url = '' url = () => { if(this.goodId == 1){ return 'json/laptop.json' } else if (this.goodId == 2) { return 'json/mobile.json' } } 

    好像不太行。url 我用 console.log 调用后显示它是个函数,而并不是一个字符串

    所以能通过箭头函数获得字符串的返回值吗?推荐这样做吗?(本意是通过箭头函数避免 var that = this 这种写法,这么写代码能跑起来)

    32 条回复    2021-02-03 21:48:22 +08:00
    DrakeXiang
        1
    DrakeXiang  
       2021-02-03 01:30:36 +08:00
    建议看一下 this 、箭头函数和函数表达式的相关知识,你这里 url 先赋值字符串,后面又赋值箭头函数,然后你还想通过 return 来改变 url 的值。。。哪儿哪儿都不对啊,简单改的话是这样

    ```Javascript
    const getJson = () => goodId === 1 ? return 'json/laptop.json' : 'json/mobile.json';
    const url = getJson();
    ```
    liyang5945
        2
    liyang5945  
       2021-02-03 01:30:51 +08:00
    你把 url 定义成一个函数了,函数必须要执行才能有返回值啊,console.log(url()),你看看是啥
    Biwood
        3
    Biwood  
       2021-02-03 01:34:18 +08:00
    不如用 Map 来写:
    const MAP_URL = { url_1: 'json/laptop.json', url_2: 'json/mobile.json' };
    const url = MAP_URL[`url_${this.goodId}`];

    非要用函数的话,可以用立即执行函数:
    url = (function(id){
    if(id == 1){
    return 'json/laptop.json'
    } else if (id == 2) {
    return 'json/mobile.json'
    }
    })(this.goodId)

    其实三元运算符也可以:
    var url = (this.goodId == 1) ? 'json/laptop.json' : (this.goodId == 2) ? 'json/mobile.json' : '';
    Rocketer
        4
    Rocketer  
       2021-02-03 02:27:48 +08:00   2
    楼上没有解决楼主的本意(避免 var that = this )

    楼主需要这么理解这件事,首先看你的主体:
    ```
    () => {
    if(this.goodId == 1) {
    return 'json/laptop.json'
    } else if (this.goodId == 2) {
    return 'json/mobile.json'
    }
    }
    ```
    这明显是个匿名函数。然后你把这个匿名函数赋给了 url,于是 url 就指向了一个函数。

    这是 Javascript 最重要的一个概念一切皆对象。函数也是对象,所以也能赋值给识别符(俗称变量名)。

    但楼主想要的不是这个函数,而是函数的返回值,所以你得让函数执行一下(套上括号,后面再加一对括号就行了)。
    ```
    (() => {
    if(this.goodId == ) {
    return 'json/laptop.json'
    } else if (this.goodId == 2) {
    return 'json/mobile.json'
    }
    })();
    ```
    然后再赋值就是你想要的字符串了。

    另外,既然你用箭头函数了,那就最好按 ES6 的标准写,别用 var 了。优选 const,const 不行就 let 。
    完整代码如下:
    ```
    let url = '';
    url = (() => {
    if(this.goodId == 1) {
    return 'json/laptop.json'
    } else if (this.goodId == 2) {
    return 'json/mobile.json'
    }
    })();
    ```
    shakaraka
        5
    shakaraka  
    PRO
       2021-02-03 02:51:48 +08:00
    你这是什么鬼啊。。

    ```
    const url = () => {
    switch(this.goodId){
    case 1:
    return 'json/laptop.json'
    case 2:
    return 'json/mobile.json'
    default:
    return ''
    }
    }
    ```

    这样不就行了?
    musi
        6
    musi  
       2021-02-03 05:25:23 +08:00 via iPhone
    你把箭头函数换成普通函数这样写 URL 的值也是个函数吧,你这又不是 IIFE 难道系统会自动帮你调用函数?
    msg7086
        7
    msg7086  
       2021-02-03 06:08:23 +08:00
    箭头函数的返回值当然就是箭头函数()啦。你不加()当然就没有调用函数了。
    sutra
        8
    sutra  
       2021-02-03 07:48:21 +08:00
    ```
    var url = ''
    var goodId = 1;

    url = (() => {
    if(goodId == 1){
    return 'json/laptop.json'
    } else if (goodId == 2) {
    return 'json/mobile.json'
    }
    })()

    console.log(url)
    ```
    randyo
        9
    randyo  
       2021-02-03 08:03:48 +08:00 via Android
    箭头函数也是函数,需要调用的
    SxqSachin
        10
    SxqSachin  
       2021-02-03 08:30:41 +08:00
    ```
    const url = (() =>{ ... })()
    ```
    meepo3927
        11
    meepo3927  
       2021-02-03 08:50:09 +08:00
    先别管箭头函数了, 了解一下 Javascript 中的函数的定义和调用吧。

    var url = '';
    url = () => {};

    上面这个写法是比较迷的,看不出来要干啥。
    vivipure
        12
    vivipure  
       2021-02-03 09:08:19 +08:00
    你就不能 const url = this.goodId == 1? '':'' ,至于 this 问题 不是在这里进行处理, 而是取决于你的调用
    cczeng
        13
    cczeng  
       2021-02-03 09:32:13 +08:00
    用 gettter 和 setter,前提是 url 是一个对象的属性

    不然调用 url 的时候 `url() ` 而不是 `url`
    TanMusong
        14
    TanMusong  
       2021-02-03 09:40:53 +08:00
    ()=>{xxx}改成
    (()=>{xxx})()
    volvo007
        15
    volvo007  
    OP
       2021-02-03 09:50:48 +08:00
    @DrakeXiang @wunonglin 人菜瘾大是这样的哈哈


    @liyang5945 看了看了,用 typeof 看是个函数,然后大概也猜到这玩意返回的是一个函数,看手册也说是个匿名函数,但是后面要怎么在代码里直接调用就懵了


    @Biwood map 这个好,学习了,特别是 $ 那个用法有点 bash 的味道啊。三元运算符主要分支会很多,不止两个。虽然三元套三元可以实现三个,不过更多的话就麻烦了


    @Rocketer 大哥你讲的是最清楚的,都明白了。最近赶鸭子上架,js 没怎么看就直接上 vue 了。回头我找个新一点的 es6 课补补。B 站的一个课 500 多节,我看到 200 多还在讲 es5,看得我崩溃……
    Elethom
        16
    Elethom  
       2021-02-03 09:54:02 +08:00 via iPhone   3
    看了楼上的回复,我觉得自己该反思一下为什么和这么多菜鸡竞争还找不到好工作了。
    volvo007
        17
    volvo007  
    OP
       2021-02-03 09:54:37 +08:00
    @TanMusong 昨晚看了官方手册,但是通篇都在讲箭头函数怎么写,各种茴的写法,没有涉及到传值的例子(这个估计会放到函数里面去讲吧)。我尝试过在参数括号前后加 () 但是还是报错,报错内容都一样的(废话),没想到是需要在最后再加一个括号调用一下
    ryncv
        18
    ryncv  
    /div>   2021-02-03 09:58:28 +08:00
    ```Javascript
    bnrwnjyw
        19
    bnrwnjyw  
       2021-02-03 10:02:14 +08:00
    这楼把我看懵了,为什么这么多半吊子指点别人啊。。。

    楼主的问题是基础不牢,连*函数*需要被*调用*才能获得返回值都搞不清楚,需要好好补补 js 基础。
    TanMusong
        20
    TanMusong  
       2021-02-03 10:11:09 +08:00
    @bnrwnjyw 也不是吧,楼主就问为啥 url 是个 function,怎么才能获得返回值。就好像有个人问 1+1 等于几,要我我就不会说 他怎么 1+1 都不会,有没有上过学,家长有没有交过之类的,告诉他等于 2 不就行了
    abc635073826
        21
    abc635073826  
       2021-02-03 10:14:10 +08:00
    你已经把 1+1 写好了,就差=了
    GopherTT
        22
    GopherTT  
       2021-02-03 10:31:18 +08:00
    先补补基础 不然天天问
    bnrwnjyw
        23
    bnrwnjyw  
       2021-02-03 10:31:53 +08:00 via iPhone
    @TanMusong 你的回复显然不是我说的那些半吊子。
    luogege
        24
    luogege  
       2021-02-03 10:38:38 +08:00
    你得先明白 url 他被你赋值成了个函数,url ()才会 return 东西
    KouShuiYu
        25
    KouShuiYu  
       2021-02-03 10:44:15 +08:00
    获得箭头函数的返回值
    ```
    let url = (()=>{
    return 'hello world';
    })()
    ```
    cw2k13as
        26
    cw2k13as  
       2021-02-03 10:44:25 +08:00
    emmm,url 你得调用啊 url(),goodId 你最好作为参数传进去啊
    darknoll
        27
    darknoll  
       2021-02-03 10:46:27 +08:00
    百度下 IIFE
    nekochyan
        28
    nekochyan  
       2021-02-03 11:45:30 +08:00
    箭头函数也是一个函数,你函数都没执行,哪来的返回值,可以立即执行一次获取返回值再赋值
    ```
    var url = (()=>{
    if(this.goodId == 1){
    return 'json/laptop.json'
    } else if (this.goodId == 2) {
    return 'json/mobile.json'
    }
    })()
    ```
    KuroNekoFan
        29
    KuroNekoFan  
       2021-02-03 12:07:29 +08:00
    你需要 this free style
    no1xsyzy
        30
    no1xsyzy  
       2021-02-03 12:14:46 +08:00
    @volvo007 500 多节到底是在讲什么?疯了吧

    就算不知道 IIFE,给它个名字然后再 call
    getURL = () => {...}
    url = getURL()
    总行吧
    LiubaiQ
        31
    LiubaiQ  
       2021-02-03 12:17:01 +08:00
    我理解的
    1. 给 url 赋值时还有额外的逻辑;
    2. 希望 this 永远指向其初始定义时的 Context;
    3. 希望通过直接赋值这样的语法来调用一个 func ;

    可以考虑 ES6 Class 及其 setter/getter 语法糖

    ```Javascript
    class c {
    ...
    set urlSetter = (v) => {
    this.url = v;
    }

    get urlGetter = (v) => this.url
    ...
    }
    ```
    fayetitus
        32
    fayetitus  
       2021-02-03 21:48:22 +08:00
    https://github.com/tc39/proposal-do-expressions
    也许你需要这个提案。
    不过 do expressions 才 stage1 。在没有 do expressions 的时候,看能不能接受 IIFE,如果不接受,那就……不优雅地写,爱咋写都行。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2491 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 174ms UTC 06:18 PVG 14:18 LAX 22:18 JFK 01:18
    Do have faith in what you're doing.
    ubao msn 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