---
type: how-to
language: javascript
slug: array/insert-remove
title: "配列の途中に入れる・途中から消す"
title_tag: "JavaScript splice() — 配列の途中に挿入・削除する方法"
summary: >
  splice() は元の配列を書き換え、消したものを返します。引数の意味、挿入と置き換え、
  ループの中で消すと1つ飛ばす理由、元を壊さない toSpliced() との使い分けまで確かめます。
description: >
  splice() の3つの引数の意味と、返り値が「消したもの」であること。ループの中で消すと
  1つ飛ばす理由と、元の配列を壊さない toSpliced() / with() の使い方まで示します。
status: published
difficulty: 2
minutes: 8

versions:
  verified: "Node 22.22.3"
  since: "ES2023"
  deprecated: null
  removed: null

sources:
  - title: "Array.prototype.splice — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-array.prototype.splice"
  - title: "Array.prototype.toSpliced — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-array.prototype.tospliced"
  - title: "Array.prototype.splice() — MDN"
    url: "https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice"

terms: [破壊的, 添字, 非破壊]

links:
  related:
    - javascript/reference/array/push
    - javascript/reference/array/slice
    - javascript/reference/array/filter
    - javascript/how-to/array/search

content_updated_at: 2026-09-09
published_at: 2026-09-09
---

## 答え

**端なら `push()` や `shift()`、途中なら `splice()` です。**

```js run
const list = ['a', 'b', 'c'];

const removed = list.splice(1, 1);

console.log(list);
console.log(removed);
```
```output
[ 'a', 'c' ]
[ 'b' ]
```

`splice(開始, 消す数, 入れるもの...)` です。

- **元の配列が書き換わります**
- 返るのは[key:消したもの]で、残ったものではありません

[bad:返り値を新しい配列だと思うと、逆のものを受け取ります。]

## 入れる・置き換える

```js run
const list = ['a', 'b', 'c'];

list.splice(1, 0, 'x', 'y');

console.log(list);
```
```output
[ 'a', 'x', 'y', 'b', 'c' ]
```

**消す数を `0` にすると、消さずに入れるだけ**になります。

```js run
const list = ['a', 'b', 'c'];

const removed = list.splice(1, 2, 'z');

console.log(list);
console.log(removed);
```
```output
[ 'a', 'z' ]
[ 'b', 'c' ]
```

消しながら入れると、置き換えになります。**数は揃っていなくて構いません。**

| やりたいこと | 書き方 |
|---|---|
| 途中から消す | `splice(i, n)` |
| 途中に入れる | `splice(i, 0, x)` |
| 置き換える | `splice(i, n, x)` |
| その位置から最後まで消す | `splice(i)` |
| 後ろから数えて消す | `splice(-1, 1)` |

```js run
const list = ['a', 'b', 'c'];

list.splice(-1, 1);

console.log(list);
```
```output
[ 'a', 'b' ]
```

## いちばんの落とし穴：ループの中で消す

```js bad
const list = [1, 2, 2, 3];

for (let i = 0; i < list.length; i++) {
  if (list[i] % 2 === 0) {
    list.splice(i, 1);
  }
}

console.log(list);
```
```output
[ 1, 2, 3 ]
```

**`2` が1つ残りました。**

消した瞬間に後ろが1つずつ前へ詰まるのに、`i` は増え続けます。
だから[bad:消した直後の1件を飛ばします]。

条件で消すだけなら、**`filter()` で作り直すのがいちばん確実**です。

```js run
console.log([1, 2, 2, 3].filter((n) => n % 2 !== 0));
```
```output
[ 1, 3 ]
```

どうしても元の配列を書き換えたいなら、**後ろから回します。**

```js run
const list = [1, 2, 2, 3];

for (let i = list.length - 1; i >= 0; i--) {
  if (list[i] % 2 === 0) {
    list.splice(i, 1);
  }
}

console.log(list);
```
```output
[ 1, 3 ]
```

後ろから消せば、**まだ見ていない側の添字は動きません。**

## 元を壊さない書き方

`toSpliced()` は、**同じことを新しい配列でやります**（ES2023）。

```js run
const list = ['a', 'b', 'c'];

console.log(list.toSpliced(1, 1));
console.log(list.toSpliced(1, 0, 'x'));
console.log(list);
```
```output
[ 'a', 'c' ]
[ 'a', 'x', 'b', 'c' ]
[ 'a', 'b', 'c' ]
```

1か所だけ差し替えるなら `with()` です。

```js run
const list = ['a', 'b', 'c'];

console.log(list.with(0, 'z'));
console.log(list);
```
```output
[ 'z', 'b', 'c' ]
[ 'a', 'b', 'c' ]
```

| | 元の配列 | 返るもの |
|---|---|---|
| `splice()` | **書き換わる** | 消したもの |
| `toSpliced()` | そのまま | **新しい配列** |
| `with()` | そのまま | **新しい配列** |

**画面の状態のように「前の値と比べる」ものは、書き換えないほうが安全**です。

## スプレッドで書く

`toSpliced()` が使えない環境なら、スプレッドで組み立てます。

```js run
const list = ['a', 'b', 'c'];
const index = 1;

console.log([...list.slice(0, index), 'x', ...list.slice(index)]);
console.log([...list.slice(0, index), ...list.slice(index + 1)]);
console.log(list);
```
```output
[ 'a', 'x', 'b', 'c' ]
[ 'a', 'c' ]
[ 'a', 'b', 'c' ]
```

`slice()` は**元を変えません。** 名前が似ていますが、`splice()` とは別物です。
→ [slice() — 元を壊さずに切り出す](/ja/javascript/reference/array/slice/)

## id で消す

実務では、添字ではなく **id で消したい**ことのほうが多いはずです。

```js run
const users = [
  { id: 1, name: 'a' },
  { id: 2, name: 'b' },
];

console.log(users.filter((user) => user.id !== 2));
```
```output
[ { id: 1, name: 'a' } ]
```

**`findIndex()` で位置を出してから `splice()` する必要はありません。**
消すだけなら `filter()` で足ります。

位置が要るときだけ探してください。

```js run
const users = [
  { id: 1, name: 'a' },
  { id: 2, name: 'b' },
];

const index = users.findIndex((user) => user.id === 2);

console.log(index);
console.log(users.toSpliced(index, 1, { id: 2, name: 'B' }));
```
```output
1
[ { id: 1, name: 'a' }, { id: 2, name: 'B' } ]
```

→ [オブジェクトの配列から探す](/ja/javascript/how-to/array/search/)

## まとめ

- `splice(開始, 消す数, 入れるもの...)`。**元が書き換わる**
- 返るのは[key:消したもの]。残ったものではない
- 消す数を `0` にすると、入れるだけになる
- **ループの中で前から消すと1件飛ばす。** `filter()` か、後ろから回す
- 元を壊したくないなら `toSpliced()` / `with()` / スプレッド
- **id で消すなら `filter()` で足りる**
