結論から云うと、素直に lastIndexOf() でドットの位置を取得して slice() か substr() するのがスピード的にはベターです
(ブラウザによっては他の手法のほうが早いことも)。パスやクエリ、アンカーからファイル名を分離するときも同様なのでは……。
【関連】拡張子のみ取得の速度テスト
[2017/04/23]
上の「計測開始」ボタンをクリックすると、ここに結果が表示されます。
※計測のタイミングにより、ある処理だけ過度に時間がかかる場合があるので、何度か計測して傾向をご確認ください
(ブラウザによる最適化のせいか、各処理の順番次第で結果が変わる場合も。
最初に計測した同じ処理のほうが時間かかりがちの傾向が……)。
// 以下が計測対象の各処理(それぞれ10万回繰り返す)
// ※ドットで始まるファイル名を隠しファイル等として特別に扱うことはしない。
// var name = fileName;
// 01: lastIndexOf() + substr()
// ----------------------------------------
var idx = name.lastIndexOf('.');
if (idx !== -1) {
extension = name.substr(idx + 1);
}
if (extension) {
baseName = name.substr(0, idx);
} else {
baseName = name;
}
// 02: lastIndexOf() + substr() + length
// ----------------------------------------
var idx = name.lastIndexOf('.');
if (idx !== -1) {
extension = name.substr(idx + 1);
}
if (extension) {
baseName = name.substr(0, name.length - extension.length - 1);
} else {
baseName = name;
}
// 03: lastIndexOf() + slice()
// ----------------------------------------
var idx = name.lastIndexOf('.');
if (idx !== -1) {
extension = name.slice(idx + 1);
}
if (extension) {
baseName = name.slice(0, idx);
} else {
baseName = name;
}
// 04: lastIndexOf() + slice() + length
// ----------------------------------------
var idx = name.lastIndexOf('.');
if (idx !== -1) {
extension = name.substr(idx + 1);
}
if (extension) {
baseName = name.slice(0, -(extension.length + 1));
} else {
baseName = name;
}
// 05: lastIndexOf() + slice() + slice(マイナス値)+ length
// ----------------------------------------
var idx = name.lastIndexOf('.');
if (idx !== -1) {
extension = name.substr(idx + 1);
}
if (extension) {
baseName = name.slice(0, name.length - extension.length - 1);
} else {
baseName = name;
}
// 06: split() + length + substr()
// ----------------------------------------
var arr = name.split('.') ;
if (arr.length !== 1) {
extension = arr[arr.length - 1];
}
if (extension) {
baseName = name.substr(0, name.length - extension.length - 1);
} else {
baseName = name;
}
// 07: split() + length + slice()
// ----------------------------------------
var arr = name.split('.') ;
if (arr.length !== 1) {
extension = arr[arr.length - 1];
}
if (extension) {
baseName = name.slice(0, name.length - extension.length - 1);
} else {
baseName = name;
}
// 08: split() + length + array.slice() + join()
// ----------------------------------------
var arr = name.split('.') ;
if (arr.length !== 1) {
extension = arr[arr.length - 1];
}
if (extension) {
baseName = arr.slice(0, arr.length - 1).join('.');
} else {
baseName = name;
}
// 09: lastIndexOf() + match()
// ----------------------------------------
if (name.lastIndexOf('.') !== -1) {
arr = name.match(/(.*)\.([^.]*$)/);
extension = arr[2];
}
if (extension) {
baseName = arr[1];
} else {
baseName = name;
}
// 10: lastIndexOf() + substr() 【※ 01 を再計測】
// ----------------------------------------
var idx = name.lastIndexOf('.');
if (idx !== -1) {
extension = name.substr(idx + 1);
}
if (extension) {
baseName = name.substr(0, idx);
} else {
baseName = name;
}
// 上記の各処理をこんなテンプレの中に入れて計測
// ----------------------------------------
var startTime;
var endTime;
var name = fileName;
startTime = new Date();
var extensionXX = (function() { // XX は 01 ~ の各番号
var extension, baseName; // 06 では arr も追加
for (var i = 0; i < 100000; i++) {
// ここに計測したい処理を記述
}
return [baseName, extension];
}());
endTime = new Date();
var timeXX = endTime - startTime + 'ms';