V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mostkia
V2EX  ›  前端开发

js 的链式调用,函数本身能区分是调用的位置吗?

  •  1
     
  •   mostkia · 2019-08-31 12:31:02 +08:00 · 3181 次点击
    这是一个创建于 1917 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如,有这样一个方法,该方法可以不断链式调用自己,并且叠加输入内容最后输出。 看着似乎挺简单的,于是按照网上的资料,我简单写了一个

    var Chain={
        sav: '',
        a1:function(val){
            this.sav = this.sav + val
            return this;
        }
    };
    Chain.a1('aaa').a1('bbb').a1('ccc');
    console.log(Chain.sav); //返回 aaabbbccc
    

    emm,好像哪里不对,想了想,原来是 return 被 this 占用了,没法输出最终的参数。

    现在有一需求:

    如何能够让 a1 这个函数,能够意识到已经是链式调用的末尾了,从而不再 return 自己( this ), 而是输出实际需要的内容呢?

    虽然可以准备一个函数专门返回 sav 的内容,这的确可以做到(比如我准备一个名为 show 的函数,里面直接返回 sav 的值):Chain.a1('aaa').a1('bbb').a1('ccc').show();

    但专门写一个 function 比较麻烦,总是跟着个小尾巴每次调用也麻烦。

    网上查了查,似乎没有什么有用资料。希望有熟悉 js 的 v 友指教一下,谢谢~

    12 条回复    2019-09-16 16:41:20 +08:00
    geelaw
        1
    geelaw  
       2019-08-31 12:54:29 +08:00 via iPhone
    这是不可能的,考虑

    var some = obj.cascade(1);
    if (SomeFunc())
    {
    console.log(some.cascade(2));
    }
    else
    {
    console.log(some);
    }

    决定是否应该返回你想要的另一个结果归结为判断 SomeFunc 是否返回真值,但这是一个不可判定问题。
    ianva
        2
    ianva  
       2019-08-31 13:03:01 +08:00
    最基本的原型方法都不明白怎么写的明白?
    ```
    class Chain {
    constructor(){
    this.save = ""
    }
    add(value){
    this.save = this.save + value;
    return this;
    }
    }
    ```
    ipwx
        3
    ipwx  
       2019-08-31 13:16:32 +08:00 via Android
    @ianva 我觉得你没审题。。。

    @mostkia 你可以在 a1 传入 null 的时候 return 最终字符串呀
    mostkia
        4
    mostkia  
    OP
       2019-08-31 13:26:30 +08:00
    @ipwx 恩,这样的确也是可以的(至少不用准备一个 show 函数了),但末尾需要额外增加 n+1 的调用,比如
    ```
    var Chain={
    sav: '',
    a1:function(val){
    if(val == null){
    return Chain.sav;
    }
    this.sav = this.sav + val
    return this;
    }
    };
    Chain.a1('aaa').a1('bbb').a1('ccc').a1();
    //返回 aaabbbccc
    ```
    目前看来还是没有很好的解决方案的样子。
    otakustay
        5
    otakustay  
       2019-08-31 13:29:34 +08:00
    你可以不需要最后那个.a1(),一个对象能实际被显示到屏幕上,或参与其它运算,绝大多数是要走 toString()和 valueOf()的,重写这 2 个就行
    ianva
        6
    ianva  
       2019-08-31 13:31:44 +08:00
    那换个玩法,https://codesandbox.io/s/reverent-kilby-wiic3
    重写 toString,或者 valueOf 可以打到部分效果
    autoxbc
        7
    autoxbc  
       2019-08-31 13:34:09 +08:00 via iPhone
    自我链式调用的场景:
    单个对象有多种方法,为了简易拼接这些方法,使得每个方法刚好接收自己的参数,而又不把这些方法和其参数都写在一整个参数序列里,才有了链式调用

    你这个场景,不要强拗,单函数多参数就完了
    flowfire
        8
    flowfire  
       2019-08-31 15:05:36 +08:00 via iPhone
    valueOf 和 toString 了解一下
    flowfire
        9
    flowfire  
       2019-08-31 15:08:40 +08:00 via iPhone
    另外你这个不叫链式调用,你这个叫 柯里化
    naeco
        10
    naeco  
       2019-08-31 16:23:58 +08:00
    @flowfire。。。
    sunjourney
        11
    sunjourney  
       2019-08-31 17:32:59 +08:00
    用 show 是正途,行为需要明确
    cjc2017
        12
    cjc2017  
       2019-09-16 16:41:20 +08:00
    @flowfire。。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2636 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 01:56 · PVG 09:56 · LAX 17:56 · JFK 20:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.