はじめに
はじめまして。learningBOX株式会社開発部開発課でフロントエンドを担当している横山です。
Internet Explorerのサポートが終了してからはや1年が経とうとしています。フロントエンドエンジニアの方々にとって衝撃的な出来事だったのではないでしょうか。
あまり馴染みのない方に簡単に説明させていただくとブラウザ(Google Chrome・Microsoft Edge・Safariなど)によって使える機能が違うのですが、Internet Explorerは特に使えない機能が多く、個別の対応となることがほとんどでした。
2022年6月15日にInternet Explorerのサポートが終了したので、主要ブラウザごとの大きな差はなくなったため開発のおける制限が少なくなりました。(弊社のサービスであるlearningBOXもInternet Explorerのサポートは終了しております)
今回は使いたくても使いにくかったECMA Scriptの新機能をご紹介させていただきます。と言ってもInternet Explorerで使用できなかったものすべてをご紹介するとなると膨大な数になるのでES2022・ES2023の中で特に私が業務でよく利用しそうだなと思ったものに限らせていただきます。
ES2022
Array.prototype.at()
at() メソッドは整数値を受け取り、その位置にある項目を返します。正の整数値と負の整数値が使用できます。負の整数は、配列の最後の項目から前へ数えます。
const array = [1, 2, 3, 4, 5];
array[0] // 1
array[array.length - 1] // 5
array[-1] // undefined
array.at(0) // 1
array.at(-1) // 5
従来の [ ] で取得する場合と大きく違うことは負の整数に対応したということです。配列の最後の項目を取得しようとした場合 array.length - 1 のような記述が必要でした。
.at() は負の整数に対応したことによって -1 を指定すれば最後の項目を取得できます。
Object.hasOwn()
Object.hasOwn() 静的メソッドは、指定されたオブジェクトが、指定されたプロパティを自身のプロパティとして持っている場合に true を返します。そのプロパティが継承されている場合、または存在しない場合、このメソッドは false を返します。
オブジェクトに指定のプロパティが存在するか確認する場合には Object.prototype.hasOwnProperty() を使用していましたが、その代わりとしてより推奨されるものになります。
なぜ .hasOwn() のほうが推奨されるかは こちら を参考にしてください。
const obj1 = Object.create(null);
const obj2 = {
prop: 1,
hasOwnProperty: function() {
return false;
},
};
obj1.hasOwnProperty('prop'); // Uncaught TypeError
Object.prototype.hasOwnProperty.call(obj1, 'prop'); // false
Object.hasOwn(obj1, 'prop'); // false
obj2.hasOwnProperty('prop'); // false;
Object.prototype.hasOwnProperty.call(obj2, 'prop'); // true
Object.hasOwn(obj2, 'prop'); // true
今までは外部オブジェクトの Object.prototype.hasOwnProperty() で存在を確認していましたが、今後は .hasOwn() を使用すれば直感的になるかと思います。
参考: Object.hasOwn()
ES2023
Array find from last
Array.prototype.findLast()
findLast() メソッドは、指定されたテスト関数を満たす配列の最後の要素の値を返します。 テスト関数を満たす要素がない場合は undefined が返されます。
Array.prototype.findLastIndex()
findLastIndex() メソッドは、指定されたテスト関数を満たす配列の最後の要素の添字を返します。 テスト関数を満たす要素がなかった場合は、 -1 を返します。
Array.prototype.find() と Array.prototype.findIndex() は テスト関数を満たす配列の最初の要素を返していましたが、.findLast() と .findLastIndex() は最後の要素を返してくれます。
const array = [5, 12, 50, 130, 44];
array.find((element) => element > 45); // 50
array.findLast((element) => element > 45); // 130
array.findIndex((element) => element > 45); // 2
array.findLastIndex((element) => element > 45); // 3
参考: Array.prototype.findLast() / Array.prototype.findLastIndex()
Change Array by copy
配列を破壊せずに操作できるメソッドが追加されました。従来の .sort() や .reverse() は元の配列を破壊してしまいます。破壊したくない場合は別途複製する必要がありました。
しかしいずれもFirefoxではサポートされていないため、polyfillを入れるなど対応が必要になります。
Array.prototype.toReversed()
Array.prototype.reverse() のコピーに相当するもので、配列の要素を逆順にした新しい配列を返すメソッドになります。
const array1 = [1, 2, 3];
const array2 = array1.reverse();
console.log(array1); // [3, 2, 1] 変更されてしまう
console.log(array2); // [3, 2, 1]
const array3 = [1, 2, 3];
const array4 = [...array3].reverse();
const array5 = array3.toReversed();
console.log(array3); // [1, 2, 3] 変更されていない
console.log(array4); // [3, 2, 1]
console.log(array5); // [3, 2, 1]
参考: Array.prototype.toReversed()
Array.prototype.toSorted()
Array.prototype.sort() のコピーに相当するもので、配列の要素をソートした新しい配列を返します。
const array1 = [3, 2, 1];
const array2 = array1.sort();
console.log(array1); // [1, 2, 3] 変更されてしまう
console.log(array2); // [1, 2, 3]
const array3 = [3, 2, 1];
const array4 = [...array3].sort();
const array5 = array3.toSorted();
console.log(array3); // [3, 2, 1] 変更されていない
console.log(array4); // [1, 2, 3]
console.log(array5); // [1, 2, 3]
参考: Array.prototype.toSorted()
Array.prototype.toSpliced
Array.prototype.splice() のコピーに相当するもので、要素を取り除いたり、置き換えたり、追加したり、変更を加えた新しい配列を返します。
const array1 = [1, 2, 3];
const array2 = array1;
array2.splice(1, 1, 20);
console.log(array1); // [1, 20, 3] 変更されてしまう
console.log(array2); // [1, 20, 3]
const array3 = [1, 2, 3];
const array4 = [...array3];
const array5 = array3.toSpliced(1, 1, 20);
array4.splice(1, 1, 20);
console.log(array3); // [1, 2, 3] 変更されない
console.log(array4); // [1, 20, 3]
console.log(array5); // [1, 20, 3]
Array.prototype.with()
指定されたインデックスの要素を指定された値に置き換えられた新しい配列を返します。
const array1 = [1, 2, 3];
const array2 = array1;
array2[1] = 20;
console.log(array1); // [1, 20, 3] 変更されてしまう
console.log(array2); // [1, 20, 3]
const array3 = [1, 2, 3];
const array4 = [...array3];
const array5 = array3.with(1, 20);
array4[1] = 20;
console.log(array3); // [1, 2, 3] 変更されていない
console.log(array4); // [1, 20, 3]
console.log(array5); // [1, 20, 3]
まとめ
今までも出来ていたことではありますが、少ない記述量でより直感的に書けるようになったと思いました。
Internet Explorerが現役の頃はECMAScriptの新機能を使う際にはpolyfillを入れたり、JavaScriptに限らずCSSにおいてもInternet Explorerだけ使えない、表示が崩れているなど大変勉強させていただきました...。
開発を取り巻く環境は日々進化を続けているので定期的にキャッチアップをしてより効率的に開発を行って不具合の少ないサービスを提供できればと思います。
今回の記事がなにか一つでも皆様の参考になれば幸いです。ここまで読んでいただきありがとうございました。