Skip to main content

How to count a string's length without built-in methods or properties (length)?

Short answer

You can count a string's length with a simple pass over the characters and a counter increment, without using length or string methods. Below are two basic variants: via for..of (counting Unicode code points) and via indexing (counting UTF-16 code units).

// Variant A: by code points (accounts for surrogate pairs) function strLengthByIteration(str) { let count = 0; for (const _ of str) count++; return count; } // Variant B: by code units (like String#length) function strLengthByIndexing(str) { let i = 0; while (true) { if (str[i] === undefined) return i; i++; } }

Detailed explanation

What exactly counts as "length"

  • Code units (UTF-16): matches the behavior of String.length and the index str[i]. Emoji outside the BMP take 2 code units.
  • Code points (Unicode code points): for..of correctly merges surrogate pairs, counting such characters as one.
  • Grapheme clusters (what a user sees as a single character): can consist of several code points (for example, ZWJ sequences and combining diacritics). Accurate counting needs a grapheme segmentation algorithm.

Solutions

  1. Counting code points without methods and length (preferred in an interview):
function codePointLength(str) { let n = 0; for (const _ of str) n++; return n; }
  1. Counting code units without methods and length (a strict repeat of String.length's logic):
function codeUnitLength(str) { let i = 0; while (true) { if (str[i] === undefined) return i; i++; } }
  1. If you need the length in grapheme clusters: without external libraries, the simplest option is the standard segmentation API (if using it is allowed):
function graphemeLength(str) { if (typeof Intl !== 'undefined' && Intl.Segmenter) { const seg = new Intl.Segmenter('en', { granularity: 'grapheme' }); let count = 0; for (const _ of seg.segment(str)) count++; return count; } // Fallback: count code points let n = 0; for (const _ of str) n++; return n; }

Verification and examples

const samples = [ "Hello", "café", "\u{1F600}", // one code point, two code units "\u{1F468}‍\u{1F469}‍\u{1F467}‍\u{1F466}", // a family: several code points, one visible character "é", // e + a combining accent, two code points, one visible character "\u0000abc" // contains a null character ]; for (const s of samples) { console.log('s =', JSON.stringify(s)); console.log('codePointLength:', codePointLength(s)); console.log('codeUnitLength :', codeUnitLength(s)); console.log('graphemeLength :', graphemeLength(s)); console.log('---'); }

Edge cases and nuances

  • Empty string: both basic algorithms return 0.
  • A null character inside the string: indexing is safe, because the check is strictly against undefined, not against truthy/falsy.
  • Emoji and characters outside the BMP: for..of accounts for surrogate pairs and gives a correct code point count.
  • Combining diacritics and ZWJ sequences: one visible character can consist of several code points; use grapheme segmentation for this.
  • Performance: all variants run in O(n) time and O(1) memory.

Complexity

Time is O(n), memory is O(1), where n is the length of the input string in the chosen unit (code units/code points/graphemes).

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.