LoginSignup
7
6

More than 5 years have passed since last update.

タグ付きテンプレート(tagged template strings)でなんちゃって演算子オーバーロード

Posted at

はじめに

  • ES2015(ES6)で追加されたタグ付きテンプレート(tagged template strings)
  • その実体は特殊な関数
    • ぱっと見は関数に見えない
  • それをつかって”なんちゃって”演算子オーバーロードをやってみようという記事
    • ※注:実用性は低いです

前提:「演算子オーバーロード」とは

JavaScript(ECMAScript)には無い概念。

JSで言えば、+とか-の演算子(operator)はnumber+string)にしか対応していない所を、例えば配列同士にも対応させようというもの。

実際には”1,2,34,5,6”という結果になる
var sum = [1,2,3] + [4,5,6]
console.log(sum)    //[5,7,9]

タグ付きテンプレートリテラル

タグ付きテンプレートリテラル(tagged template strings)とは、通常のテンプレート文字列の前にタグの文字列がついたものだ。

タグ付きテンプレートの例
var str = tag`文字列${変数}`

文字列と呼ばれているが、実は中身は関数へのシンタックスシュガーになっており、returnする中身もstringである必要はない。

文字数(number)を返すタグ付きテンプレート
"use strict";

function count(a,...args){
  let aSum = 0;
  a.map((v,i,a)=> aSum += v.length)
  let argSum = 0;
  args.map((v,i,a)=>{argSum += v.length})
  return aSum + argSum
}

var str = "お米"
console.log( count`おいしい${str}` )  //6

タグ付きテンプレートになる関数の特徴

  • 第一引数はrawというプロパティを持った特別な配列
    • TypeScriptではTemplateStringsArray
    • それ自体、およびrawプロパティは文字列の配列
    • キャッシュされる
  • 第二引数以降は、${}で括った変数の値がそのまま入る
    • 文字列に限らない

パッと見、関数に見えないので…

タグ付きテンプレートの特徴を使ってなんちゃって演算子オーバーロードをやってみる。

配列同士の加算

var sum = A`${[1,2,3]} + ${[4,5,6]}`

console.log(sum) //[5,7,9]

Aの中身

function A(arr, a1, a2){
  const op = arr[1].replace(/[\s]/g,"");
  switch(op){
    case "+":
      const longer = (a1.length >= a2.length)? a1 : a2
      const shorter = (a1.length < a2.length)? a1 : a2
      const l = shorter.length
      for(let i=0;i<l;i++){
        longer[i] = longer[i] + shorter[i]
      }
      return longer;
      break;
    default:
      throw Error();
  }
}

制限

  • 上記の例では加算のみ
  • 項目が2つまで
    • ただし次のようにする事はできる:
A`${[0,1]} + ${ A`${[1,1]} + ${[5,5]}` }`
  • 記号が多い
    • A([0,1,2],"+",[3,4,5])の方が見やすい!?

一応メリット

補足

valueOfを使った疑似演算子オーバーロード

Reflect.defineOperator


  1. エラーはSIMD型の定義が無いから。simd.d.tsをDLしてください。 

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6