easyJS ES5#103

String ends with (no built-in)

Prompt

Given two strings, return true if the first string ends with the second. Do NOT use String.prototype.endsWith. An empty ending returns true.

Solution

function endsWith(str, ending) {
  if (ending.length === 0) return true
  if (ending.length > str.length) return false
  return str.slice(-ending.length) === ending
}
Mentor's take

"Reimplement a built-in" questions test whether you know the semantics of the method you use daily — and the edge cases the spec had to decide. The pattern: take the suffix of the right length with a negative slice and compare. str.slice(-n) returns the last n characters, so the whole comparison is one line. O(n) time in the ending's length, O(n) space for the slice; the naive loop comparing character-by-character from the end is the same complexity, just more code and more off-by-one surface.

Two guards do the real work. First, if the ending is longer than the string, no suffix can match — return false before slicing. Second, and this is the trap: slice(-0) is slice(0), because -0 === 0. With an empty ending, str.slice(-ending.length) returns the whole string, not the empty string, so the comparison wrongly fails. The native endsWith returns true for an empty search string; your reimplementation must special-case it.

Red flag: skipping the empty-ending guard. It's the exact kind of bug that passes every test you thought of and fails the one the interviewer has ready. Reaching for a regex here is also a miss — escaping the ending correctly is harder than the problem.

Say it: "Negative slice gives me the suffix in one line — the guards exist because slice(-0) is slice(0) and an oversized ending can never match."