Author: Abdullah Numan
What is Iteration?
There are other iteration methods which are not as often used, but when needed are always handy tools for iterating over arrays, strings and objects.
every() are such examples.
Some iteration methods, like
Array.prototype.forEach() iterates over all items in a collection and some like
Array.prototype.slice() iterates over the array partially.
We will cover several of these methods in this series, each in their own post.
String prototypes. We'll get into their nuances with examples of both of these types.
JS slice -
Array.prototype.slice() is an
Array method that is used to extract a contiguous portion from an existing array. It can take two arguments: the
start and the
end indicator of the slice -- both of which are optional:
// Method signature slice(); slice(start); slice(start, end);
In this section, we set off with an example that expounds some general cases for selecting and storing a section from a source array. Then we'll see a couple of more interesting examples that help us generate arrays from arguments passed to a function using
Slicing an Array
A typical examples of slicing an array involves extracting a contiguous part from an existing array. Such as the first three items, last three items and some items spanning from a certain index up until another index, as shown in the examples below:
const elements = ['Please', 'Send', 'Cats', 'Monkeys', 'And', 'Zebras', 'In', 'Large', 'Cages', 'Make', 'Sure', 'Padlocked']; const firstThree = elements.slice(0, 3); const lastThree = elements.slice(-3, elements.length); const fromThirdToFifth = elements.slice(2, 5);
Both arguments of
slice() stand for zero-based index numbers or negative offset values. The first one (
0 in the
firstThree assignment above) represents the starting index or offset in the source array where slicing should begin and the second one (
3) is the index or offset before which extraction should stop.
If we log the extracted values above, we can see the three elements we want from each slice:
console.log(firstThree); // ["Please", "Send", "Cats"] console.log(lastThree); // ["Make", "Sure", "Padlocked"] console.log(fromThirdToFifth); // ["Cats", "Monkeys", "And"]
It is important to notice that the item represented by the second argument is excluded from the extracted part. And we should be careful that unlike in
Array.prototype.splice(), whose second argument is the count of items to be deleted, the second argument of
Array.prototype.slice() does not stand for the number of items to be extracted, rather the position before which slicing should stop.
If we don't pass in any argument, we just get a shallow copy of the source array with all items:
const allCopied = elements.slice(); console.log(allCopied); // (12) ["Please", "Send", "Cats", "Monkeys", "And", "Zebras", "In", "Large", "Cages", "Make", "Sure", "Padlocked"]
No Second Argument
const fromThird = elements.slice(2); const lastThree = elements.slice(-3, elements.length); const lastThreeWithNoSecArg = elements.slice(-3); console.log(fromThird); // (10) ["Cats", "Monkeys", "And", "Zebras", "In", "Large", "Cages", "Make", "Sure", "Padlocked"] console.log(lastThree); // (3) ["Make", "Sure", "Padlocked"] console.log(lastThreeWithNoSecArg); // (3) ["Make", "Sure", "Padlocked"]
Do notice that
lastThreeWithNoSecArg evaluates to the same portion as
lastThree, albeit missing the second argument.
As we've already seen above, we can pass in as arguments negative numbers that denote offset positions counted backwards from the last item. We can do this for both arguments:
const latestTwoBeforeLast = elements.slice(-3, -1); console.log(latestTwoBeforeLast); // (2) ["Make", "Sure"]
latestTwoBeforeLast, we're getting the latest two items without the final one.
Starting Position Greater Than Ending Position
If we pass in a greater value for
end, we get an empty array:
const somewhereWeDontKnow = elements.slice(5, 2); console.log(somewhereWeDontKnow); // 
Starting Position Greater Than Length of Array
Likewise, if we pass in a greater value for
start than array's
length, we get an empty array:
const somewhereInOuterSpace = elements.slice(15, 2); console.log(somewhereInOuterSpace); // 
If we our target portion has sparse items, they are also copied over:
const elements = ['Please', 'Send', , 'Cats', , 'Monkeys', 'And', 'Zebras', 'In', 'Large', 'Cages', 'Make', 'Sure', 'Padlocked']; const sparseItems = elements.slice(0, 6); console.log(sparseItems); // (6) [ 'Please', 'Send', <1 empty item>, 'Cats', <1 empty item>, 'Monkeys' ]
Creating Arrays from a List of Arguments
Now we can go a bit crazy about slicing. Let's construct an array from a list of arguments passed to a function:
const createArray = (...args) => Array.prototype.slice.call(args); const array = createArray(1, 2, 3, 4); console.log(array); // (4) [1, 2, 3, 4]
Here, we received
args as a list first, but converted it to an array with rest params
...args. We then bound the array to
That was easy.
The next level way of doing this is in the messiest possible way:
const boundSlice = Function.prototype.call.bind(Array.prototype.slice); const createArray = (...args) => boundSlice(args); const array = createArray(1, 2, 3, 4); console.log(array); // (4) [1, 2, 3, 4]
It seems like a overhead, but what were are doing is declaring two helper functions.
The first one,
boundSlice, is derived from binding the
Function.prototype.call() method with
Array.prototype.slice() which is an array function object. So, we are getting a copy of
Function.prototype.call() bound to
Array.prototype.slice() and storing it in
This basically means, if we invoke
boundSlice(), we are in effect invoking
Array.prototype.slice.call(). If we then pass in an argument list as rest params to
Array.prototype.slice() is invoked on this array and a copy of the array is created from it.
createArray(), we are accumulating the arguments and passing them to
args. So, whatever we pass to
createArray() is returned as items inside an array.
JS slice -
slice() method for strings.
String.prototype.slice() does the exact same thing as
Array.prototype.slice(), but with characters in a string.
Array.prototype.slice(), it takes two optional arguments,
// Method signature slice(); slice(start); slice(end);
Slicing a String
String.prototype.slice() is useful for directly working on strings. It removes the hassle of converting a string to an array with
const mnemonic = 'Please Send Cats Monkeys And Zebras In Large Cages Make Sure Padlocked'; const firstThreeChars = mnemonic.slice(0, 3); const lastThreeChars = mnemonic.slice(-3, mnemonic.length); const fromThirdToFifthChars = mnemonic.slice(2, 5); console.log(firstThreeChars); // "Ple" console.log(lastThreeChars); // "ked" console.log(fromThirdToFifthChars); // "eas"
Again, both arguments represent zero-based index numbers or negative offset values. Here, the first one,
0 in the
firstThree assignment, stands for the starting index or offset of the portion and the second one (
3) for the index or offset before which extraction should stop.
With No Arguments
If we don't pass in any arguments, we get a new copy of the whole string:
const mnemonic = 'Please Send Cats Monkeys And Zebras In Large Cages Make Sure Padlocked'; const memorizedMnemonic = mnemonic.slice(); console.log(memorizedMnemonic); // "Please Send Cats Monkeys And Zebras In Large Cages Make Sure Padlocked"
With No Second Argument
If we don't pass the second argument, the
length of the string becomes
const charsFromThird = mnemonic.slice(2); console.log(charsFromThird); // "ease Send Cats Monkeys And Zebras In Large Cages Make Sure Padlocked"
Array.prototype.slice(), negative values for
end represent offset positions from the end of the array:
const lastThreeChars = mnemonic.slice(-3); const latestTwoCharsBeforeLast = mnemonic.slice(-3, -1); console.log(lastThreeChars); // "ked" console.log(latestTwoCharsBeforeLast); // "ke"
Starting Position Greater Than Ending Position or Length of Array
Again, similar to
start is greater than
length of string, we get an empty string:
const inAnotherDimension = mnemonic.slice(5, 2); const doingStringTheory = mnemonic.slice(15, 2); console.log(inAnotherDimension); // "" console.log(doingStringTheory); // ""
Stop wasting your time copy/pasting your table code all over your application!
Meet the headless, React-based solution to build sleek CRUD applications. With refine, you can be confident that your codebase will always stay clean and boilerplate-free.
Try refine to rapidly build your next CRUD project, whether it's an admin panel, dashboard, internal tool or storefront.
In this post, we expounded the
slice() in two flavors: one for
Array.prototype.slice() and one for
String.prototype.slice(). We found out through examples that both methods are used to extract contiguous portions from a source object representing these types.
We also saw that
String.prototype.slice() is identical implementation of
Array.prototype.slice() that removes the overhead of converting a string to an array of characters.
We also covered how function composition and context binding with
Function.prototype.bind() allows us to define custom functions that help us generate arrays from a list of arguments.