LoginSignup
10
8

More than 3 years have passed since last update.

【JavaScript】破壊的メソッドの非破壊的な書き方

Last updated at Posted at 2021-04-17

破壊的メソッドの何がまずいのか?

破壊的メソッドを使うとコードの読み手に混乱を与えてしまう可能性があります。

破壊的メソッドを使った例

const numbers = [1, 2, 3, 4, 5];

// とても長い処理
numbers.push(6); <- 読み飛ばされてしまう可能性が高い
// とても長い処理

console.log(numbers); <- 読み手は[1, 2, 3, 4, 5]を期待している
// 実際は[1, 2, 3, 4, 5, 6]; 

非破壊的メソッドを使った例

const numbers = [1, 2, 3, 4, 5];

// とても長い処理
const newNumbers = numbers.concat(6);
// とても長い処理

console.log(numbers); // [1, 2, 3, 4, 5] 読み手の期待通りのまま
console.log(newNumbers); // [1, 2, 3, 4, 5, 6]

結論

スプレッド構文を使えばOK!
以下、具体的な書き方と別の書き方をまとめます。

目次

push()
unshift()
pop()
shift()
sort()
reverse()
copyWithin()

push()

Array.prototype.push()

push() メソッドは、配列の末尾に 1 つ以上の要素を追加することができます。また戻り値として新しい配列の要素数を返します。

破壊

const numbers = [1, 2, 3, 4, 5];
numbers.push(6);
console.log(numbers); // [1, 2, 3, 4, 5, 6]

非破壊

// スプレッド構文
const numbers = [1, 2, 3, 4, 5];
const newNumbers = [...numbers, 6];
console.log(numbers); // [1, 2, 3, 4, 5]
console.log(newNumbers); // [1, 2, 3, 4, 5, 6]

// concat()
const numbers = [1, 2, 3, 4, 5];
const newNumbers = numbers.concat(6);
console.log(numbers); // [1, 2, 3, 4, 5]
console.log(newNumbers); // [1, 2, 3, 4, 5, 6]

unshift()

Array.prototype.unshift()

unshift() メソッドは、配列の最初に 1 つ以上の要素を追加し、新しい配列の長さを返します。

破壊

const numbers = [1, 2, 3, 4, 5];
numbers.unshift(0);
console.log(numbers); // [0, 1, 2, 3, 4, 5]

非破壊

// スプレッド構文
const numbers = [1, 2, 3, 4, 5];
const newNumbers = [0, ...numbers];
console.log(numbers); // [1, 2, 3, 4, 5]
console.log(newNumbers); // [0, 1, 2, 3, 4, 5]

// concat()
const numbers = [1, 2, 3, 4, 5];
const newNumbers = [0].concat(numbers);
console.log(numbers); // [1, 2, 3, 4, 5]
console.log(newNumbers); // [0, 1, 2, 3, 4, 5]

pop()

Array.prototype.pop()

pop() メソッドは、配列から最後の要素を取り除き、その要素を返します。このメソッドは配列の長さを変化させます。

破壊

const numbers = [1, 2, 3, 4, 5];
numbers.pop();
console.log(numbers); // [1, 2, 3, 4]

非破壊

// スプレッド構文
const numbers = [1, 2, 3, 4, 5];
const newNumbers = [...numbers];
newNumbers.pop()
console.log(numbers); // [1, 2, 3, 4, 5]
console.log(newNumbers); // [1, 2, 3, 4]

// slice()
const numbers = [1, 2, 3, 4, 5];
const newNumbers = numbers.slice(0, 4);
console.log(numbers); // [1, 2, 3, 4, 5]
console.log(newNumbers); // [1, 2, 3, 4]

shift()

Array.prototype.shift()

shift() メソッドは、配列から最初の要素を取り除き、その要素を返します。このメソッドは配列の長さを変えます。

破壊

const numbers = [1, 2, 3, 4, 5];
numbers.shift();
console.log(numbers); // [2, 3, 4, 5]

非破壊

// スプレッド構文
const numbers = [1, 2, 3, 4, 5];
const newNumbers = [...numbers];
newNumbers.shift();
console.log(numbers); // [1, 2, 3, 4, 5]
console.log(newNumbers); // [2, 3, 4, 5]


// slice()
const numbers = [1, 2, 3, 4, 5];
const newNumbers = numbers.slice(1, 5);
console.log(numbers); // [1, 2, 3, 4, 5]
console.log(newNumbers); // [2, 3, 4, 5]

sort()

Array.prototype.sort()

sort() メソッドは、配列の要素を in place でソートします。既定のソート順は昇順で、要素を文字列に変換してから、UTF-16 コード単位の値の並びとして比較します。

破壊

const numbers = [5, 1, 4, 2, 3];
numbers.sort();
console.log(numbers); // [1, 2, 3, 4, 5]

非破壊

// スプレッド構文
const numbers = [5, 1, 4, 2, 3];
newNumbers = [...numbers].sort()
console.log(numbers); // [5, 1, 4, 2, 3]
console.log(newNumbers); // [1, 2, 3, 4, 5]

reverse()

Array.prototype.reverse()

reverse() メソッドは、配列の要素を In-place アルゴリズムで反転させます。最初の要素が最後の要素に、最後の要素が最初の要素になります。

破壊

const numbers = [1, 2, 3, 4, 5];
numbers.reverse();
console.log(numbers); // [5, 4, 3, 2, 1]

非破壊

// スプレッド構文
const numbers = [1, 2, 3, 4, 5];
newNumbers = [...numbers].reverse()
console.log(numbers); // [1, 2, 3, 4, 5]
console.log(newNumbers); // [5, 4, 3, 2, 1]

fill()

Array.prototype.fill()

fill() メソッドは、開始インデックス(デフォルトは 0)から終了インデックス(デフォルトは array.length)までのすべての要素を、静的な値に変更した配列を返します。

破壊

const numbers = [1, 2, 3, 4, 5];
numbers.fill(7);
console.log(numbers); // [7, 7, 7, 7, 7]

非破壊

// スプレッド構文
const numbers = [1, 2, 3, 4, 5];
newNumbers = [...numbers].fill(7)
console.log(numbers); // [1, 2, 3, 4, 5]
console.log(newNumbers); // [7, 7, 7, 7, 7]

copyWithin()

Array.prototype.copyWithin()

copyWithin() メソッドは、サイズを変更せずに、配列の一部を同じ配列内の別の場所にシャローコピーして返します。

破壊

const numbers = [1, 2, 3, 4, 5];
numbers.copyWithin(2, 3, 5);
console.log(numbers); // [ 1, 2, 4, 5, 5 ]

非破壊

// スプレッド構文
const numbers = [1, 2, 3, 4, 5];
newNumbers = [...numbers].copyWithin(2, 3, 5);
console.log(numbers); // [1, 2, 3, 4, 5]
console.log(newNumbers); // [ 1, 2, 4, 5, 5 ]

参考

10
8
2

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
10
8