# Add \`.splice\` to \`String.prototype\`

**URL:** <https://es.discourse.group/t/add-splice-to-string-prototype/2242>\
**Category:** 🦋 Proposals\
**Tags:** proposal\
**Created:** [December 16, 2024, 7:45pm UTC](https://es.discourse.group/t/add-splice-to-string-prototype/2242 "2024-12-16T19:45:31Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![zion-off](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/zion-off/32/2324_2.png) [@zion-off](https://es.discourse.group/u/zion-off)\
**Post date:** [December 16, 2024, 7:45pm UTC](https://es.discourse.group/t/add-splice-to-string-prototype/2242/1 "2024-12-16T19:45:31Z")

</div>

#### Proposal: [GitHub - zion-off/proposal-string-splice: A TC39 proposal to add .splice() to String.prototype](https://github.com/zion-off/proposal-string-splice?tab=readme-ov-file)

## Overview

In JavaScript, `String.prototype` and `Array.prototype` share a good few

methods. However, `String.prototype` is missing `.splice()`, which happens to be

quite useful when working with arrays. Currently, the method can be simulated

when working with strings in a few different ways.

## Examples

Consider the following example, where I want add the character `c` to `myString`

at the second index.

```js

let myString = "abde";

// using `String.prototype.slice`

let firstHalf = myString.slice(0, 2);

let secondHalf = myString.slice(2);

myString = firstHalf + "c" + secondHalf;

// using `Array.prototype` methods

myString.split("").splice(2, 0, "c").join("");

```

Both of these methods get the job done, but are unnecessarily verbose. With a pure function such as `String.prototype.splice`, we can achieve the same effect far more easily.

```js

myString.splice(2, 0, "c");

```

## Specification

[Ecmarkup source](https://zion-off.github.io/)

[HTML](https://zion-off.github.io/proposal-string-splice/)

## Acknowledgements

Although a similar proposal exists [here](https://es.discourse.group/t/proposal-string-tospliced/2142), this propsal maintains consistency in nomenclature between `Array.prototype` and `String.prototype` methods.

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [December 16, 2024, 7:59pm UTC](https://es.discourse.group/t/add-splice-to-string-prototype/2242/2 "2024-12-16T19:59:29Z")

</div>

On arrays, splice mutates, and strings are immutable. If we were to add this, I'd expect it to be called "toSpliced".

That said, I think the API of splice is incredibly confusing, and it'd be more useful to look at what problems this is solving and how that can be best achieved, rather than cargoculting the worst Array method over to strings :-)

---

<div class="post-metadata">

**Author:** ![zion-off](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/zion-off/32/2324_2.png) [@zion-off](https://es.discourse.group/u/zion-off)\
**Post date:** [December 17, 2024, 9:37pm UTC](https://es.discourse.group/t/add-splice-to-string-prototype/2242/3 "2024-12-17T21:37:10Z")

</div>

makes sense, i just thought it'd be neat addition since i have to do string splicing manually a lot. thank you for explaining it so nicely! : )

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [December 17, 2024, 9:48pm UTC](https://es.discourse.group/t/add-splice-to-string-prototype/2242/4 "2024-12-17T21:48:05Z")

</div>

Can you elaborate a bit more on your use cases for string splicing?

---

<div class="post-metadata">

**Author:** ![zion-off](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/zion-off/32/2324_2.png) [@zion-off](https://es.discourse.group/u/zion-off)\
**Post date:** [December 18, 2024, 5:09am UTC](https://es.discourse.group/t/add-splice-to-string-prototype/2242/5 "2024-12-18T05:09:06Z")

</div>

this would be really useful for normalizing phone number inputs:

```javascript
let phone = "1234567890";
let formatted = phone.splice(3, 0, "-").splice(7, 0, "-");
console.log(formatted); // Output: "123-456-7890"

```

or dynamically inserting markup:

```javascript
let text = "The quick brown fox";
let query = "quick";
let index = text.indexOf(query);
let highlighted = text.splice(index, 0, "<b>").splice(index + query.length + 3, 0, "</b>");
console.log(highlighted); // Output: "The <b>quick</b> brown fox"

```

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [December 18, 2024, 5:44am UTC](https://es.discourse.group/t/add-splice-to-string-prototype/2242/6 "2024-12-18T05:44:59Z")

</div>

Given the complexity of the phone numbers people input (including symbols, area codes, country codes, etc), and of working with markup at all, I'm confused why you wouldn't prefer to use regular expressions and proper parsers rather than string manipulation?

---

<div class="post-metadata">

**Author:** ![MaxArt](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/maxart/32/2315_2.png) [@MaxArt](https://es.discourse.group/u/MaxArt)\
**Post date:** [December 18, 2024, 9:03am UTC](https://es.discourse.group/t/add-splice-to-string-prototype/2242/7 "2024-12-18T09:03:17Z")

</div>

I think that's just an example, but a replacement method could be indeed useful for several cases (I've thought about that during this Advent of Code, haha). For the sake of DX, I'd define a signature like this:

```js
String.prototype.replaceSubstring = function(index, replacement, length = replacement.length) {
  return this.slice(0, index) + replacement + this.slice(index + length);
};

```

It'd be sweet to have other methods like `.with` (a special case of `.replaceSubstring`, in this case) or even `.toReversed`.

Edit: I've used `replace` as a "new" method - that would have been confusing, as there's already one - rather than a new signature for the method. For the sake of simplicity, I've renamed it with `replaceSubstring`.

---

<div class="post-metadata">

**Author:** ![zion-off](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/zion-off/32/2324_2.png) [@zion-off](https://es.discourse.group/u/zion-off)\
**Post date:** [December 18, 2024, 9:34am UTC](https://es.discourse.group/t/add-splice-to-string-prototype/2242/8 "2024-12-18T09:34:53Z")

</div>

exactly! i thought of splice since, if implemented like Array.prototype.splice, it'd let you delete a substring without you having to pass in an empty string as the replacement string

---

<div class="post-metadata">

**Author:** ![zion-off](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/zion-off/32/2324_2.png) [@zion-off](https://es.discourse.group/u/zion-off)\
**Post date:** [December 18, 2024, 9:40am UTC](https://es.discourse.group/t/add-splice-to-string-prototype/2242/9 "2024-12-18T09:40:35Z")

</div>

to be fair i've only discussed this with other engineers at work and the general consensus was that it would be convenient to have a method like this. let me run this idea past some community members online and hopefully i'll be able get back to you with some more thought out, diverse use cases.

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [December 19, 2024, 4:25am UTC](https://es.discourse.group/t/add-splice-to-string-prototype/2242/10 "2024-12-19T04:25:27Z")

</div>

I'm not particularly fond of either of those use-case examples. The problem with both of them is that you're calling `.splice()` multiple times in a row, causing the index in the later calls to be effected by what got spliced in the earlier calls. One way to solve this would be to reverse the order of the `.splice()` so you splice the later text before the earlier one, but I think the most straight-forward solution would be to use the methods that are already currently available, like this:

Instead of:

```javascript
let phone = "1234567890";
let formatted = phone.splice(3, 0, "-").splice(7, 0, "-");
console.log(formatted); // Output: "123-456-7890"

```

You could do this:

```javascript
let phone = "1234567890";
let formatted = phone.slice(0, 3) + "-" + phone.slice(3, 6) + "-" + phone.slice(6);
console.log(formatted); // Output: "123-456-7890"

```

Notice how we can use 6 instead of 7, because we're not having to account for the fact that a "-" was already added earlier in the string, because the new string is being created in one go, instead of in steps.

Same thing with the markup example. Instead of this:

```javascript
let text = "The quick brown fox";
let query = "quick";
let index = text.indexOf(query);
let highlighted = text.splice(index, 0, "<b>").splice(index + query.length + 3, 0, "</b>");
console.log(highlighted); // Output: "The <b>quick</b> brown fox"

```

We can have this (where you don't have to add an extra `3` to account for the 3 characters in `<b>`).

```javascript
let text = "The quick brown fox";
let query = "quick";
let index = text.indexOf(query);
let highlighted = text.slice(0, index) + "<b>" + text.slice(index, index + query.length) + "</b>" + text.slice(index + query.length);
console.log(highlighted); // Output: "The <b>quick</b> brown fox"

```

Perhaps there are string helper methods we could add to improve this kind of use-case of inserting characters in the middle of the string, but I don't think `.splice()` does a particularly good job of it.

---

<div class="post-metadata">

**Author:** ![zion-off](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/zion-off/32/2324_2.png) [@zion-off](https://es.discourse.group/u/zion-off)\
**Post date:** [December 19, 2024, 4:41am UTC](https://es.discourse.group/t/add-splice-to-string-prototype/2242/11 "2024-12-19T04:41:09Z")

</div>

i see why string splice isn't already a thing! it seems existing methods already do a good enough job and .splice adds less convenience than new things to worry about.
