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 == nullto catch bothnullandundefinedcases. The Promise to avoid reassignment warnings (e.g., ifundefinedis shadowed) is implicitly handled here via宽松 comparison rather thenvoid 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 coercelengthinto 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 nativereduce.
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])
callbackreceives(accumulator, currentValue, currentIndex, array)initialValueis optional; if omitted and the array is empty,TypeErroris thrown