Underscore.js Differences
_.m aims to be as compatible with Underscore.js as possible, but some differences exist due to language differences between JavaScript and Objective-C.
Not Supported
Section titled “Not Supported”The following Underscore.js functions are not available in _.m:
| Function | Reason |
|---|---|
bind | Objective-C blocks capture scope automatically |
bindAll | Not applicable |
isElement | No DOM in Objective-C |
isRegExp | Different regex API |
isUndefined | Objective-C has nil instead |
noConflict | Not applicable |
mixin | Different extension model |
escape | Different string escaping needs |
template | Different templating approach |
No Context Parameter
Section titled “No Context Parameter”In Underscore.js, many functions accept an optional context parameter:
// JavaScript_.each(list, iterator, context);In _.m, blocks automatically capture their surrounding scope, so context is not needed:
// Objective-C - context captured automatically__weak typeof(self) weakSelf = self;_.each(list, ^(id item, ...) { [weakSelf doSomething:item];});Type Differences
Section titled “Type Differences”| JavaScript | Objective-C |
|---|---|
undefined | nil |
null | nil or [NSNull null] |
Array | NSArray |
Object | NSDictionary |
Function | Block (^) |
Variadic Arguments
Section titled “Variadic Arguments”_.m uses ... (va_list) for optional iterator arguments:
// Block signature includes ... for optional key and list_.each(list, ^(id value, ...) { // Access optional args via va_list if needed});Helper Macros
Section titled “Helper Macros”_.m provides macros for extracting variable arguments in blocks:
Collection Iteration (no terminators needed)
Section titled “Collection Iteration (no terminators needed)”| Macro | Description |
|---|---|
ARGS_KEY(value) | Extracts the key (second argument) |
ARGS_INDEX(value) | Extracts the index (second argument) |
ARGS_LIST(value, LIST_NAME) | Extracts the list (third argument) |
Variable Arguments (terminators required)
Section titled “Variable Arguments (terminators required)”| Macro | Description |
|---|---|
ARGS_AO(NAME, lastNamedArg) | Collects all id objects after the specified argument (nil-terminated) |
ARGS_AI(NAME, lastNamedArg) | Collects all integers after the specified argument (AI_END-terminated) |
Single Argument Extraction
Section titled “Single Argument Extraction”| Macro | Description |
|---|---|
ARG_B() | Extract one BOOL |
ARG_I() | Extract one NSInteger |
ARG_UI() | Extract one NSUInteger |
ARG_F() | Extract one float |
ARG_D() | Extract one double |
ARG_N() | Extract one NSNumber* |
ARG_NSO() | Extract one NSObject* |
Block Type Definitions
Section titled “Block Type Definitions”_.m defines block types for consistency:
| Block Type | Signature | Usage |
|---|---|---|
_EachBlock | ^(id value, ...) | Iteration without return |
_EachWithStopBlock | ^B(id value, ...) | Returns boolean to control loop |
_MapBlock | ^id(id value, ...) | Returns transformed value |
_ReduceBlock | ^id(id memo, id value, ...) | Accumulation function |
_FindBlock | ^B(id value) | Predicate for finding |
_ItemTestBlock | ^B(id value, ...) | Predicate for filtering |
_MaxBlock / _MinBlock | ^id(id value) | Comparison function |
_SortByBlock | ^id(id value, ...) | Returns sort key |
_GroupByBlock | ^id(id value, ...) | Returns grouping key |
_DelayBlock / _DeferBlock | ^() | No arguments, no return |
_ThrottleBlock | ^id() | Returns id |
_DebounceBlock | ^(id arg1, ...) | Variable arguments |
_OnceBlock | ^id(id arg1, ...) | Execute once |
_AfterBlock | ^id(id arg1, ...) | Execute after N calls |
_WrapBlock | ^id(_WrappedBlock wrapped, id arg1, ...) | Wraps another block |
_ComposeBlock | ^id(id arg1, ...) | Function composition |
_TapBlock | ^(id obj) | Side-effect interceptor |
_TimesBlock | ^(I index) | Iteration N times |
_IdentityBlock | ^id(id value) | Returns unchanged value |
Memory Management
Section titled “Memory Management”_.m is fully ARC compatible. When capturing self in blocks, use __weak to avoid retain cycles:
__weak typeof(self) weakSelf = self;_.each(items, ^(id item, ...) { [weakSelf processItem:item];});Type Shortcuts
Section titled “Type Shortcuts”_.m provides shorthand type aliases for cleaner code:
// Instead ofNSArray* result = ...;NSDictionary* dict = ...;
// UseA* result = ...;O* dict = ...;See the Introduction for the full list of type shortcuts.