JavaScriptで変数付きsetterのようなことはできますか？


JavaScriptではオブジェクトにsetterを用意すれば代入の操作で複雑な処理が行えますが、

[code]

    var o = {
        set current(a) {
            console.log(a)
        },
    };
    o.current = 1; //console => 1
    
[/code]

同じように代入で処理をしたいのですが、プロパティに変数をつけたようにはできないでしょうか。厳密にsyntaxが以下のようである必要はありませんが、`...=...`の形にはしたいです。

[code]

    o.current(2) = 1; //2*1, console => 2
    o.current(4) = 1; //4*1, console => 4
    o.current(4) = 2; //4*2, console => 8
    
[/code]

変数は文字列ではない予定なので`Proxy`の`handler.get(target, propertyName,
receiver)`では少し試したのではできなさそうでしたが、よくはわかってないです。




`()`を付けると関数の呼び出し形式になり、左辺値には使えなくなります。  
`[]`で代用するとして、`Proxy` を使うのであれば、`get` ではなく `set` になると思います。

[code]

    const current_hdl = {
     set: (_, name, val) => {
      console.log(Number(name) * val);
      return true;
     }
    };
    const current = new Proxy({}, current_hdl);
    
    let o = { current: current }
    o.current[2] = 1; //2*1, console => 2
    o.current[4] = 1; //4*1, console => 4
    o.current[4] = 2; //4*2, console => 8
[/code]

追記: 「変数は文字列ではない」というのが、文字列（プロパティ名）として表現不可能、という意味であれば上記は使えないかもしれませんね。

* * *

数字を複数渡すとのことなので、やはり packet0 さんの回答のように関数にするしかないですね。  
少し一般化し、

[code]

    o.method(right, ...lefts);
    
[/code]

への構文糖として

[code]

    o.param(...lefts).method = right;
    // あるいは
    o.method = right;
    
[/code]

を用意する例です。

[code]

    let o = {
     param: (...lefts) => {
      function setter(target, name, val){
       target[name](val, ...lefts);
       return true;
      }
      return new Proxy(o, {set: setter});
     },
     get current(){
      return (right, ...lefts) => {
       lefts.push(right);
       console.log(lefts);
      }
     },
     set current(right){
      o.current(right);
     },
    };
    
    o.param(1, 2).current = 10; // console => [ 1, 2, 10 ]
    o.current(10, 1, 2); // 上と同じ
    
    o.param().current = 10; // console => [ 10 ]
    o.current = 10; // 上と同じ
    o.current(10); // 上と同じ
[/code]




`()`を付けると関数の呼び出し形式になり、左辺値には使えなくなります。  
`[]`で代用するとして、`Proxy` を使うのであれば、`get` ではなく `set` になると思います。

[code]

    const current_hdl = {
     set: (_, name, val) => {
      console.log(Number(name) * val);
      return true;
     }
    };
    const current = new Proxy({}, current_hdl);
    
    let o = { current: current }
    o.current[2] = 1; //2*1, console => 2
    o.current[4] = 1; //4*1, console => 4
    o.current[4] = 2; //4*2, console => 8
[/code]

追記: 「変数は文字列ではない」というのが、文字列（プロパティ名）として表現不可能、という意味であれば上記は使えないかもしれませんね。

* * *

数字を複数渡すとのことなので、やはり packet0 さんの回答のように関数にするしかないですね。  
少し一般化し、

[code]

    o.method(right, ...lefts);
    
[/code]

への構文糖として

[code]

    o.param(...lefts).method = right;
    // あるいは
    o.method = right;
    
[/code]

を用意する例です。

[code]

    let o = {
     param: (...lefts) => {
      function setter(target, name, val){
       target[name](val, ...lefts);
       return true;
      }
      return new Proxy(o, {set: setter});
     },
     get current(){
      return (right, ...lefts) => {
       lefts.push(right);
       console.log(lefts);
      }
     },
     set current(right){
      o.current(right);
     },
    };
    
    o.param(1, 2).current = 10; // console => [ 1, 2, 10 ]
    o.current(10, 1, 2); // 上と同じ
    
    o.param().current = 10; // console => [ 10 ]
    o.current = 10; // 上と同じ
    o.current(10); // 上と同じ
[/code]

