Zepto iOS 3 Compatibility Module: trim and reduce Polyfills

The IOS3 module in Zepto provides backward compatibility for older iOS versions (specifically iOS 3.x) by implementing polyfills for two commonly used yet missing methods: String.prototype.trim and Array.prototype.reduce.

trim Polyfill

The native String.prototype.trim is unavailable in iOS 3.2, so Zepto defines it only if it doesn’t already exist:

if (String.prototype.trim === undefined) {
  String.prototype.trim = function () {
    return this.replace(/^\s+|\s+$/g, '')
  }
}

This implementation strips leading and trailing whitespace using a regular expression. ^\s+ matches one or more whitespace characters at the start, and \s+$ matches those at the end.

reduce Polyfill

Historically, iOS 3.x lacked support for Array.prototype.reduce. Zepto includes a full polyfill based on the MDN implementation:

if (Array.prototype.reduce === undefined) {
  Array.prototype.reduce = function (callback) {
    if (this == null) throw new TypeError('Convertible value is null or undefined')
    const object = Object(this)
    const length = object.length >>> 0
    if (typeof callback !== 'function') throw new TypeError('Callback must be a function')

    let index = 0
    let accumulator
    if (arguments.length > 1) {
      accumulator = arguments[1]
    } else {
      for (; index < length; index++) {
        if (index in object) {
          accumulator = object[index]
          index++
          break
        }
      }
      if (index >= length) throw new TypeError('Reduce of empty array with no initial value')
    }

    for (; index < length; index++) {
      if (index in object) {
        accumulator = callback.call(undefined, accumulator, object[index], index, object)
      }
    }
    return accumulator
  }
}

Key Implementation Details

  • Null/Undefined Check: Uses this == null to catch both null and undefined cases. The Promise to avoid reassignment warnings (e.g., if undefined is shadowed) is implicitly handled here via宽松 comparison rather then void 0.
  • Casting to Object: Converts the receiver to an object via Object(this) to support array-like objects (e.g., arguments, strings).
  • Safe Length: Uses the unsigned right shift operator (>>> 0) to coerce length into a non-negative integer.
  • Initial Value Handling: If no second argument is passed, the first existing element in the object becomes the initial accumulator. This ensures sparse arrays are handled correctly — skipped indices are ignored.
  • Callback Execution: Calls callback.call(undefined, accumulator, currentValue, currentIndex, object) exactly like native reduce.

The loop only processes defined indices via the index in object check, preserving the spec-compliant behavior for sparse arrays.

Standard Usage

As per the ECMA-262 spec:

arr.reduce(callback[, initialValue])
  • callback receives (accumulator, currentValue, currentIndex, array)
  • initialValue is optional; if omitted and the array is empty, TypeError is thrown

Tags: polyfill ios-3 trim reduce zepto-source

Posted on Mon, 03 Aug 2026 16:59:20 +0000 by deepakagrawal1982