tl;dr at the end.
In terms of 'performance', js engines are pretty well optimized. For something like this, performance should not be part of your argument against a given piece of code. In terms of readability, they are very similar so either works. There are better ways to think through this though.
When it comes to PRs I would ponder on a few questions:
- What does the PR code in question actually change?
Between the two snippets of code, there are no changes to the API of the calling code and no implementation changes to accommodate any edge cases. They work the same way and there are no visible upsides. So why change it? Original takes it here. DFWAB!
- Does the code add/remove unnecessary steps?
const parts = someString.split('.');
return parts[parts.length - 1];
This reads as:
- Split
someString
into an ('.'
character delimited) array
- Label (step 1)
parts
- Take
parts
's length
property and subtract 1
- Retrieve
parts
's element at index
(step 3)
return
(step 4)
const [last] = someString.split('.').reverse();
return last;
This reads as:
- Split
someString
into an ('.'
delimited) array
reverse
the elements in (step 1)
- Label the first element in (step 2)
last
return
last
Here the PR code changes the approach and removes a step. Is it necessary though? This is more left to opinion, and I am sure you will get opinions for/against both. IMHO "split an array then reverse that array" are simpler to reason about because it is declarative. I can see a string being split into pieces in my head and then reverse
-ing the original order so the first element becomes the last (supported by the const label last
). In the original, I have to reason about arrays, their properties, and why I have to access its length at all. I say that the PR code takes this. Not by much though.
- What is the intention of the code?
This code's intention regardless of implementation is to take a string and give back a substring starting one character after the last '.'
in the string. Both implementations perform acrobatics just to pull this off. The main fault in terms of implementation is 'why do we have to turn the string into an array' when the string possesses all the necessary methods?
Here is an example that beats out both cases and how it performs in these metrics:
return someString.slice(someString.lastIndexOf('.') + 1);
- No changes from the original code BUT adds clear benefits. (win)
- Removes unnecessary/takes fewer steps and is more declarative. (win)
- States the true intention of the code clearly. (huge win)
BONUS: IT'S A ONE LINER! WOOHOO!
Now I know people tend to not see this as a benefit but I think shorter code with higher stats (as described above) is better than more code performing equally or worse.
The code reads as:
- Take
someString
and find the lastIndexOf
'.'
- Add
1
to (step 1)
slice
someString
starting at the index (step 2)
return
(step 3)
Just a small note: if I were certain that this was all the code in the calling function I would turn it into someString => someString.slice(someString.lastIndexOf('.') + 1)
and eliminate step 4 since the return is implicit and the function can be seen as the result of the first three steps.
In terms of intention, this line is literally saying (as the steps also describe): "Slice this string starting at the index following the last index of '.'
. It's just clear.
tl;dr
Neither one is 'right' because performance is irrelevant and both snippets are fairly similar in readability. Instead of 'readability' (whatever that means, highly subjective) look at these metrics when it comes to PRs:
- Does the PR actually implement changes? (original wins)
- Does the PR add/remove unnecessary STEPS? (PR wins)
- Does the pull request make the intention of the code clearer? (tied loss)
A better change which beats the other two in all categories (for reference) could be something like this:
return someString.slice(someString.lastIndexOf('.') + 1);
parts[parts.length - 1]
is considered "hard to read"? \$\endgroup\$parts[parts.length - 1]
part. \$\endgroup\$parts[parts.length - 1]
is somehow hard to read. \$\endgroup\$const [last] = array
in any way difficult to read, let alone considered an obfuscation? Anyone familiar with object destructuring (so common in React now) ought to at least have some basic understanding of its cousin, array destructuring. I think more important to the code review the OP did was if that change was even necessary to begin with as it appears to have been a completely superfluous implementation change on the coder's part. "Just because" isn't really a valid reason to change working production code. \$\endgroup\$