KamilTroczewski

Misleading methods 🤷‍♂️

💡

This article is available in Polish too. If you'd like then

Have you ever used a method split, splice, or slice? If you had and you have never looked into documentation while using it, you are a lucky guy. I always need to take a look because all of them are so similar to each other. However, maybe there is a way how to differentiate them? Let's see.

Splice

Splice changes a structure of an array - removes elements, replaces them or adds new ones. The first argument it takes is an index that indicates starting point. The second argument is optional and specifies a number of elements to modify. Other arguments are also optional and define elements that we want to add. However, don't forget that splice mutates a content of an array!

// splice(start, deleteCount, element1, element2, elementN)

const array = ['zero', 'first', 'second', 'third'];

array.splice(2, 0, 'element-1', 'element-2');

["zero", "first", "element-1", "element-2", "second", "third"]
console.log(array)

// remove two elements from index -2 (it's 2nd from the end)
const removed = array.splice(-2, 2);

// ["second", "third"] 
console.log(removed);

// ["zero", "first", "element-1", "element-2"]
console.log(array)

// Removes everything from index 0 to the end
array.splice(0);

// []
console.log(array);

Slice

Despite beeing very similar to splice it has one huge difference - it returns shallow copy of an array, so in practice we have a reference that points to this array.

If the slice returns an object of the array and one value in this array is changed, this change will have a serious impact on a starting array - because now we will be working on a reference! It's a very huge threat. When someone will make a modification on that object later, some weird and unexpected situations can occur. We can prevent that by using deep copy. Then every mutation won't change both arrays.

// Shallow copy
const array = [{ value: 'zero' }, { value: 'first' }, { value: 'second' }, { value: 'third' }];

const shallow = array.slice(0, 1);
shallow[0].value = 'modified';

// { value: 'modified' };
console.log(array[0]);

// Deep copy
const array2 = [{ value: 'zero' }, { value: 'first' }, { value: 'second' }, { value: 'third' }];

const deep = JSON.parse(JSON.stringify(array2.slice(0, 1)));
deep[0].value = 'modified';

// { value: 'zero' };
console.log(array2[0]);

We can use Slice on string prototype too. It allows to extract specific fragments of a text. It's usage is similar to an array usage. As the first argument, it takes starting index and as a second - an ending index.

const introduction = 'Hi! My name is Kamil';

const name = introduction.slice(-5);

// Kamil
console.log(name);

const greeting = introduction.slice(0, 3);

// Hi!
console.log(greeting);

Split

Split creates a new array with smaller parts of the string, that has been divided. It takes the separator as an argument. For example, it could be a space, comma, or even a long fragment of text.

const sentence = 'It\'s a piece of cake';

// It splits on every space
const splitted = sentence.split(' ');

// ["It's", 'a', 'piece', 'of', 'cake']
console.log(splitted);

As a curiosity, the spread operator for a string, works in the same way as a split with an empty string.

const sentence = 'Halooo!';

// [...sentence] -> sentence.split('')
const splitted = [...sentence]; 

// ['H', 'e', 'l', 'l', 'o', 'o', 'o', '!']
console.log(sentence)

Summary

Despite the similarities, we can actually differentiate these methods. Slice can be used either for string or array. But split and splice can be used only for arrays. Surely, our IDE plays a huge role is while suggesting arguments that methods take. I hope that next time when I'll be using those methods I wouldn't need to take a look at the documentation. But we all know how it happens in life - our memory is good but short 🤷‍♂️