Zepto Internal Utility Functions Explained

Zepto implements a set of lightweight, purpose-built utility functions to handle common operations on arrays, strings, and JavaScript types—without relying on external dependencies or heavy abstractions. These helpers form the foundation for higher-level APIs and reflect thoughtful design choices around browser compatibility, performance, and edge-case handling.

Array Utilities

Zepto begins by caching native array methods to avoid repeated property lookups:

const EMPTY_ARRAY = [];
const arrayConcat = EMPTY_ARRAY.concat;
const arrayFilter = EMPTY_ARRAY.filter;
const arraySlice = EMPTY_ARRAY.slice;

compact()

Removes falsy values equivalent to null or undefined:

function compact(input) {
  return arrayFilter.call(input, item => item != null);
}

This leverages loose equality (!=) so both null and undefined coerce to false and are filtered out. Strict comparison (!==) would require explicit checks for both values.

flatten()

Performs single-level flattening—only unwraps immediate nested arrays:

function flatten(input) {
  return input.length ? arrayConcat.apply([], input) : input;
}

The use of apply spreads the input array as individual arguments to concat, effectively merging top-level elements: [1, [2, 3], 4][1, 2, 3, 4]. Deep nesting like [1, [[2]]] remains unchanged.

uniq()

Removes duplicate entries while preserving order:

function uniq(input) {
  return arrayFilter.call(input, (item, index) => input.indexOf(item) === index);
}

An element is retained only if its first occurrence in the array matches its current position—ensuring uniqueness without side effects or external state.

String Transformations

camelize()

Converts kebab-case strings into camelCase:

function camelize(str) {
  return str.replace(/-+(.)/g, (_, char) => char ? char.toUpperCase() : '');
}

The regex matches one or more hyphens followed by any character; that character is capitalized and the hyphens omitted. For example, "data-user-id" becomes "dataUserId".

dasherize()

Converts PascalCase or mixed-case identifiers into lowercase kebab-case:

function dasherize(str) {
  return str
    .replace(/::/g, '/')
    .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
    .replace(/([a-z\d])([A-Z])/g, '$1_$2')
    .replace(/_/g, '-')
    .toLowerCase();
}

Each step progressively inserts underscores before capitol letters (accounting for acronyms and transitions), then replaces underscores with hyphens and lowercaess everything. Input "XMLHttpRequest" yields "x-m-l-http-request".

Type Detection System

Zepto avoids typeof’s limitations (e.g., typeof [] === "object") by using Object.prototype.toString for precise classification:

const TYPE_MAP = Object.create(null);
const toString = Object.prototype.toString;

'Boolean Number String Function Array Date RegExp Object Error'.split(' ').forEach(name => {
  TYPE_MAP[`[object ${name}]`] = name.toLowerCase();
});

type()

Returns a normalized lowercase type string:

function type(value) {
  return value == null ? String(value) : TYPE_MAP[toString.call(value)] || 'object';
}

Handles null and undefined explicitly (returning "null" or "undefined"), otherwise delegates to the map. Fallback to "object" covers host objects and unrecognized natives.

Helper Predicates

Derived from type():

function isFunction(val) { return type(val) === 'function'; }
function isObject(val)   { return type(val) === 'object'; }
function isWindow(val)   { return val != null && val === val.window; }
function isDocument(val) { return val != null && val.nodeType === 9; }
function isPlainObject(val) {
  return isObject(val) && !isWindow(val) && Object.getPrototypeOf(val) === Object.prototype;
}

Note: isDocument relies on DOCUMENT_NODE === 9, per DOM specification.

isArray()

Uses feature detection with graceful fallback:

const isArray = Array.isArray || (val => toString.call(val) === '[object Array]');

Unlike instanceof Array, this approach works across frames and execution contexts because toString is deterministic and environment-agnostic.

likeArray()

Determines whether an object resembles an array—supporting iteration and length-based access:

function likeArray(obj) {
  const len = obj && 'length' in obj ? obj.length : 0;
  const t = type(obj);

  return t !== 'function' &&
         !isWindow(obj) &&
         (t === 'array' || len === 0 || (
           typeof len === 'number' &&
           len > 0 &&
           (len - 1) in obj
         ));
}

A "like-array" must have a numeric length, support bracket notation up to length - 1, and not be a function or window. This enables uniform handling of arguments, DOM collections, and custom array-like structures.

Tags: zepto utility-functions type-detection array-methods string-manipulation

Posted on Sun, 30 Aug 2026 16:53:51 +0000 by dotBz