文字列を切り取る組み込み関数はslice、substring、substrで、使い勝手はほぼ同じ。使い分ける意味があるのだろうか? 当初は処理速度だけ検証するつもりだったが…。
共通の挙動
第一引数
- 省略
全ての文字列を叩き返す - 0
- 第二引数を省略した場合、全ての文字列を叩き返す
- 第二引数が正数の場合、第二引数番目までの文字列を叩き返す
- 正数
- 第二引数を省略した場合、第一引数番目から切り取った文字列を叩き返す
3つの関数全てに言える事は、引数を省略するなら全く使う意味が無い。
let a="0123456789",z=a.length
with(console)
log(a.slice()),
log(a.slice(0)),
log(a.slice(0,z)),
log(a.slice(0,z>>1)),
log(a.slice(z>>1)),
log(a.substr()),
log(a.substr(0)),
log(a.substr(0,z)),
log(a.substr(0,z>>1)),
log(a.substr(z>>1)),
log(a.substring()),
log(a.substring(0)),
log(a.substring(0,z)),
log(a.substring(0,z>>1)),
log(a.substring(z>>1))
slice
第一引数
- 0以上
先頭から数えた位置 - 負数
末尾から数えた位置。-1が末尾
第二引数
- 0
実質無意味 - 正数
先頭から数えた位置 - 負数
末尾の直前から数えた位置。末尾は指定不可
let a="0123456789"
with(console)
log(a.slice(2,4)), // 23
log(a.slice(-2)), // 89
log(a.slice(2,-2)), // 234567
log(a.slice(-4,-2)), // 67
log(a.slice(0,-1)) // 012345678
substring
第一引数
- 0以上
先頭から数えた位置 - 負数
不可。0と挙動は同じ
第二引数
- 0以上
先頭から数えた位置 - 負数
不可。0と挙動は同じ
sliceと同様、引数は文字列の位置を指す(0基点)。負数を指定できない点が異なる。正数の場合の相違は、第一引数が第二引数より大きくても差分を切り取る事。
let a="0123456789"
with(console)
log(a.substring(2,4)), // 23
log(a.substring(4)), // 456789
log(a.substring(4,3)), // 3
log(a.substring(4,2)), // 23
log(a.substring(4,1)), // 123
log(a.substring(4,0)) // 0123
substr
第一引数
- 0以上
先頭から数えた位置 - 負数
末尾から数えた位置。-1が末尾
第二引数
- 0以上
切り取る長さ - 負数
不可
Internet Explorer6等、一部のBrowserは負数の第一引数に対応していない。
let a="0123456789"
with(console)
log(a.substr(2,4)), // 2345
log(a.substr(4)), // 456789
log(a.substr(4,3)), // 456
log(a.substr(-2,2)), // 89
log(a.substr(-4,2)) // 67
benchmark
では同じ挙動を示す処理でどれほどの速度差がでるのか検証。
for(let a=4,s=Array(1e5).join(0),z=s.length;a--;console.log(a)){
console.time`slice`;
for(let b=32;b--;)for(let a=z;a--;)s.slice(a)
console.timeEnd`slice`;
console.time`str`;
for(let b=32;b--;)for(let a=z;a--;)s.substr(a)
console.timeEnd`str`;
console.time`string`;
for(let b=32;b--;)for(let a=z;a--;)s.substring(a)
console.timeEnd`string`;
}
Google Chromeでは大して変わらん…。ちなみに引数を省略するより引数に0を指定した方が遥かに高速だった
使い分け
substrは長さを指定するので使いやすい。sliceとsubstringは第二引数が位置なので面倒になりやすいという印象。