MochiKit Back to docs index

Name

MochiKit.Base - functional programming and useful comparisons

Synopsis

myObjectRepr = function () {
    // gives a nice, stable string representation for objects,
    // ignoring any methods
    var keyValuePairs = [];
    for (var k in this) {
        var v = this[k];
        if (typeof(v) != 'function') {
            keyValuePairs.push([k, v]);
        }
    };
    keyValuePairs.sort(compare);
    return "{" + map(
        function (pair) {
            return map(repr, pair).join(":");
        },
        keyValuePairs
    ).join(", ") + "}";
};

// repr() will look for objects that have a repr method
myObjectArray = [
    {"a": 3, "b": 2, "repr": myObjectRepr},
    {"a": 1, "b": 2, "repr": myObjectRepr}
];

// sort it by the "a" property, check to see if it matches
myObjectArray.sort(keyComparator("a"));
expectedRepr = '[{"a": 1, "b": 2}, {"a": 3, "b": 2}]';
assert( repr(myObjectArray) == expectedRepr );

// get just the "a" values out into an array
sortedAValues = map(itemgetter("a"), myObjectArray);
assert( compare(sortedAValues, [1, 3]) == 0 );

// serialize an array as JSON, unserialize it, expect something equivalent
myArray = [1, 2, "3", null, undefined];
assert( objEqual(evalJSON(serializeJSON(myArray)), myArray) );

Description

MochiKit.Base is the foundation for the MochiKit suite. It provides:

Python users will feel at home with MochiKit.Base, as the facilities are quite similar to those available as part of Python and the Python standard library.

Dependencies

None.

Overview

Comparison

The comparators (operators for comparison) in JavaScript are deeply broken, and it is not possible to teach them new tricks.

MochiKit exposes an extensible comparison facility as a simple compare(a, b) function, which should be used in lieu of JavaScript's operators whenever comparing objects other than numbers or strings (though you can certainly use compare for those, too!).

The compare function has the same signature and return value as a sort function for Array.prototype.sort, and is often used in that context.

Defining new comparators for the compare function to use is done by adding an entry to its AdapterRegistry with the registerComparator function.

Programmer Representation

JavaScript's default representation mechanism, toString, is notorious for having terrible default behavior. It's also very unwise to change that default, as other JavaScript code you may be using may depend on it.

It's also useful to separate the concept of a "string representation" and a "string representation for programmers", much like Python does with its str and repr protocols.

repr provides this programmer representation for JavaScript, in a way that doesn't require object prototype hacking: using an AdapterRegistry.

Objects that implement the repr protocol can either implement a .repr() or .__repr__() method, or they can simply have an adapter setup to generate programmer representations. By default, the registry provides nice representations for null, undefined, Array, and objects or functions with a NAME attribute that use the default toString. For objects that repr doesn't already understand, it simply defaults to toString, so it will integrate seamlessly with code that implements the idiomatic JavaScript toString method!

To define a programmer representation for your own objects, simply add a .repr() or .__repr__() method that returns a string. For objects that you didn't create (e.g., from a script you didn't write, or a built-in object), it is instead recommended that you create an adapter with registerRepr.

JSON Serialization

JSON [1], JavaScript Object Notation, is a widely used serialization format in the context of web development. It's extremely simple, lightweight, and fast. In its essence, JSON is a restricted subset of JavaScript syntax suitable for sending over the wire that can be unserialized with a simple eval. It's often used as an alternative to XML in "AJAX" contexts because it is compact, fast, and much simpler to use for most purposes.

To create a JSON serialization of any object, simply call serializeJSON() with that object. To unserialize a JSON string, simply call evalJSON() with the serialization.

In order of precedence, serializeJSON coerces the given argument into a JSON serialization:

  1. Primitive types are returned as their JSON representation: string, number, boolean, null.
  2. If the object has a toJSON, __json__ or json method, then it is called with no arguments. If the result of this method is not the object itself, then the new object goes through rule processing again (e.g. it may return a string, which is then serialized in JSON format).
  3. If the object is Array-like (has a length property that is a number, and is not a function), then it is serialized as a JSON array. Each element will be processed according to these rules in order. Elements that can not be serialized (e.g. functions) will be replaced with undefined.
  4. The jsonRegistry AdapterRegistry is consulted for an adapter for this object. JSON adapters take one argument (the object), and are expected to behave like a __json__ or json method (return another object to be serialized, or itself).
  5. If the object is undefined, a TypeError is thrown. If you wish to serialize undefined as null or some other value, you should create an adapter to do so.
  6. If no adapter is available, the object is enumerated and serialized as a JSON object (name:value pairs). All names are expected to be strings. Each value is serialized according to these rules, and if it can not be serialized (e.g. methods), then that name:value pair will be skipped.

Adapter Registries

MochiKit makes extensive use of adapter registries, which enable you to implement object-specific behaviors for objects that you do not necessarily want to modify, such as built-in objects. This is especially useful because JavaScript does not provide a method for hiding user-defined properties from for propName in obj enumeration.

AdapterRegistry is simply an encapsulation for an ordered list of "check" and "wrap" function pairs. Each AdapterRegistry instance should perform one function, but may have multiple ways to achieve that function based upon the arguments. One way to think of it is as a poor man's generic function, or multiple dispatch (on arbitrary functions, not just type!).

Check functions take one or more arguments, and return true if the argument list is suitable for the wrap function. Check functions should perform "cheap" checks of an object's type or contents, before the "expensive" wrap function is called.

Wrap functions take the same arguments as check functions and do some operation, such as creating a programmer representation or comparing both arguments.

Convenience Functions

Much of MochiKit.Base is there to simply remove the grunt work of doing generic JavaScript programming.

Need to take every property from one object and set them on another? No problem, just call update(dest, src)! What if you just wanted to update keys that weren't already set? Look no further than setdefault(dest, src[, ...]).

Want to return a mutable object, but don't want to suffer the consequences if the user mutates it? Just clone(it) and you'll get a copy-on-write clone. Cheaper than a copy!

Need to extend an Array with another array? Or even an Array-like object such as a NodeList or the special arguments object? Even if you need to skip the first few elements of the source Array-like object, it's no problem with extend(dstArray, srcArrayLike[, skip])!

Wouldn't it be convenient to have all of the JavaScript operators were available as functions somewhere? That's what the operators table is for, and it even comes with additional operators based on the compare function.

Need to walk some tree of objects and manipulate or find something in it? A DOM element tree perhaps? Use nodeWalk(node, visitor)!

There's plenty more, so check out the API Reference below.

Functional Programming

Functional programming constructs such as map and filter can save you a lot of time, because JavaScript iteration is error-prone and arduous. Writing less code is the best way to prevent bugs, and functional programming can help you do that.

MochiKit.Base ships with a few simple Array-based functional programming constructs, namely map and filter, and their "extended" brethren, xmap and xfilter.

map(func, arrayLike[, ...]) takes a function and an Array-like object, and creates a new Array. The new Array is the result of func(element) for every element of arrayLike, much like the Array.prototype.map extension in Mozilla. However, MochiKit.Base takes that a step further and gives you the full blown Python version of map, which will take several Array-like objects, and calls the function with one argument per given Array-like, e.g.:

var arrayOne = [1, 2, 3, 4, 5];
var arrayTwo = [1, 5, 2, 4, 3];
var arrayThree = [5, 2, 1, 3, 4];
var biggestElements = map(objMax, arrayOne, arrayTwo, arrayThree);
assert( objEqual(biggestElements, [5, 5, 3, 4, 5]) );

filter(func, arrayLike[, self]) takes a function and an Array-like object, and returns a new Array. This is basically identical to the Array.prototype.filter extension in Mozilla. self, if given, will be used as this in the context of func when called.

xmap and xfilter are just special forms of map and filter that accept a function as the first argument, and use the extra arguments as the Array-like. Not terribly interesting, but a definite time-saver in some cases.

If you appreciate the functional programming facilities here, you should definitely check out MochiKit.Iter, which provides full blown iterators, MochiKit.Iter.range, MochiKit.Iter.reduce, and a near-complete port of Python's itertools [2] module, with some extra stuff thrown in for good measure!

Bound and Partial Functions

JavaScript's method-calling special form and lack of bound functions (functions that know what this should be) are one of the first stumbling blocks that programmers new to JavaScript face. The bind(func, self) method fixes that right up by returning a new function that calls func with the right this.

In order to take real advantage of all this fancy functional programming stuff, you're probably going to want partial application. This allows you to create a new function from an existing function that remembers some of the arguments. For example, if you wanted to compare a given object to a slew of other objects, you could do something like this:

compareWithOne = partial(compare, 1);
results = map(compareWithOne, [0, 1, 2, 3]);
assert( objEqual(results, [-1, 0, 1, 1]) );

One of the better uses of partial functions is in MochiKit.DOM, which is certainly a must-see for those of you creating lots of DOM elements with JavaScript!

API Reference

Errors

NotFound:

A singleton error raised when no suitable adapter is found

Availability:
Available in MochiKit 1.3.1+

Constructors

AdapterRegistry:

A registry to facilitate adaptation.

All check/wrap function pairs in a given registry should take the same number of arguments.

Availability:
Available in MochiKit 1.3.1+

AdapterRegistry.prototype.register(name, check, wrap[, override]):

name:
a unique identifier used to identify this adapter so that it may be unregistered.
check:
function that should return true if the given arguments are appropriate for the wrap function.
wrap:
function that takes the same parameters as check and does the adaptation. Every wrap/check function pair in the registry should have the same number of arguments.
override:
if true, the check function will be given highest priority. Otherwise, the lowest.
Availability:
Available in MochiKit 1.3.1+

AdapterRegistry.prototype.match(obj[, ...]):

Find an adapter for the given arguments by calling every check function until one returns true.

If no suitable adapter is found, throws NotFound.

Availability:
Available in MochiKit 1.3.1+

AdapterRegistry.prototype.unregister(name):

Remove a named adapter from the registry

Availability:
Available in MochiKit 1.3.1+

NamedError:

Convenience constructor for creating new errors (e.g. NotFound)

Availability:
Available in MochiKit 1.3.1+

Functions

arrayEqual(self, arr):

Compare the arrays self and arr for equality using compare on each element. Uses a fast-path for length differences.

Availability:
Available in MochiKit 1.3.1+

average(lst[, ...]):

This function is an alias of mean().

Availability:
Available in MochiKit 1.3.1+

bind(func, self[, arg, ...]):

Return a copy of func bound to self. This means whenever and however the returned function is called, this will always reference the given self. func may be either a function object, or a string. If it is a string, then self[func] will be used, making these two statements equivalent:

bind("method", self);
bind(self.method, self);

Calling bind(func, self) on an already bound function will return a new function that is bound to the new self! If self is undefined, then the previous self is used. If self is null, then the this object is used (which may or may not be the global object). To force binding to the global object, you should pass it explicitly.

Additional arguments, if given, will be partially applied to the function. These three expressions are equivalent and return equally efficient functions (bind and partial share the same code path):

Availability:
Available in MochiKit 1.3.1+

bindLate(func, self[, arg, ...]):

Alternate version of bind that uses late lookup of the func parameter in self. I.e, the self[func] function lookup will occur on each call to the returned function, not when bindLate is called. Note that this difference is only applicable when func is a string, otherwise bindLate and bind are identical.

Availability:
Available in MochiKit 1.4+

bindMethods(self):

Replace all functions meth on self with bind(meth, self). This emulates Python's bound instance methods, where there is no need to worry about preserving this when the method is used as a callback.

Availability:
Available in MochiKit 1.3.1+

bool(value):

Converts value into a boolean. The conversion varies depending on typeof(value):

  1. A boolean value is returned as-is.
  2. A string value is considered false if and only if it equals "", "false", "null", "undefined" or "0".
  3. A number value is considered false if and only if isNaN(value) or value == 0.
  4. A array-like value is considered false if and only if value.length == 0.
  5. Any other value is considered false if and only if value == null.
Availability:
Available in MochiKit 1.5+

camelize(str):

Converts hyphenated strings to camelCase:

assert( camelize("border-left") == "borderLeft" );
Availability:
Available in MochiKit 1.4+

clone(obj):

Return a new object using obj as its prototype. Use this if you want to return a mutable object (e.g. instance state), but don't want the user to mutate it. If they do, it won't have any effect on the original obj.

Note that this is a shallow clone, so mutable properties will have to be cloned separately if you want to "protect" them.

Availability:
Available in MochiKit 1.3.1+

compare(a, b):

Compare two objects in a sensible manner. Currently this is:

  1. undefined and null compare equal to each other
  2. undefined and null are less than anything else
  3. If JavaScript says a == b, then we trust it
  4. comparators registered with registerComparator are used to find a good comparator. Built-in comparators are currently available for Array-like and Date-like objects.
  5. Otherwise hope that the built-in comparison operators do something useful, which should work for numbers and strings.
  6. If neither a < b or a > b, then throw a TypeError

Returns what one would expect from a comparison function:

Value Condition
0 a == b
1 a > b
-1 a < b
Availability:
Available in MochiKit 1.3.1+

compose(f1, f2, ..., fN):

Return a new function as the combination of the given function arguments, equivalent to f1(f2(arguments)).

Availability:
Available in MochiKit 1.4+

concat(lst[, ...]):

Concatenates all given Array-like arguments and returns a new Array:

var lst = concat(["1","3","5"], ["2","4","6"]);
assert( lst.toString() == "1,3,5,2,4,6" );
Availability:
Available in MochiKit 1.3.1+

counter(n=1):

Returns a function that will return a number one greater than the previous returned value, starting at n. For example:

nextId = counter()
assert( nextId() == 1 )
assert( nextId() == 2 )

For an iterator with this behavior, see MochiKit.Iter.count.

Availability:
Available in MochiKit 1.3.1+

extend(self, obj, skip=0):

Mutate the array self by extending it with an Array-like obj, starting from index skip. If null is given as the initial array, a new one will be created.

This mutates and returns self, be warned.

Availability:
Available in MochiKit 1.3.1+

evalJSON(jsonText):

Unserialize a JSON [1] representation of an object.

Note that this uses the eval function of the interpreter, and therefore trusts the contents of jsonText to be safe. This is acceptable when the JSON and JavaScript application originate from the same server, but in other scenarios it may not be the appropriate security model. Currently, a validating JSON parser is beyond the scope of MochiKit, but in most modern browsers the JSON.parse function is built-in for this purpose. There is also one available from json.org [1].

Availability:
Available in MochiKit 1.3.1+

filter(fn, lst):

Returns a new Array composed of all elements from lst where fn(lst[i]) returns a true value.

If fn is null, operator.truth will be used.

Availability:
Available in MochiKit 1.3.1+

findValue(lst, value, start=0, end=lst.length):

Finds the index of value in the Array-like object lst using compare. The search starts at the index start, and ends at the index end - 1. If value is not found in lst, it will return -1.

For example:

assert( findValue([1, 2, 3, 2, 1], 2) == 1 )
assert( findValue([1, 2, 3, 2, 1], 2, 2) == 3 )
Availability:
Available in MochiKit 1.3.1+

findIdentical(lst, value, start=0, end=lst.length):

Finds the index of value in the Array-like object lst using the === operator. The search starts at the index start, and ends at the index end - 1. If value is not found in lst, it will return -1.

You should use this function instead of findValue if lst may be comprised of objects for which no comparator is defined and all you care about is finding an identical object (e.g. the same instance), or if lst is comprised of just numbers or strings and performance is important.

For example:

assert( findIdentical([1, 2, 3, 2, 1], 2) == 1 )
assert( findIdentical([1, 2, 3, 2, 1], 2, 2) == 3 )
Availability:
Available in MochiKit 1.3.1+

flattenArguments(arg[, ...]):

Given a bunch of arguments, return a single Array containing all of those arguments. Any Array-like argument will be extended in-place, e.g.:

compare(flattenArguments(1, [2, 3, [4, 5]]), [1, 2, 3, 4, 5]) == 0
Availability:
Available in MochiKit 1.3.1+

flattenArray(lst):

Return a new Array consisting of every item in lst with Array items expanded in-place recursively. This differs from flattenArguments in that it only takes one argument and it only flattens items that are instanceof Array.

compare(flattenArray([1, [2, 3, [4, 5]]]), [1, 2, 3, 4, 5]) == 0
Availability:
Available in MochiKit 1.4+

forwardCall(name):

Returns a function that forwards a method call to this.name(...)

Availability:
Available in MochiKit 1.3.1+

isArrayLike(obj[, ...]):

Returns true if all given arguments are Array-like (have a .length property and typeof(obj) == 'object')

Availability:
Available in MochiKit 1.3.1+

isCallable(obj[, ...]):

Returns true if all given arguments are functions.

Availability:
Available in MochiKit 1.3.1+

isDateLike(obj[, ...]):

Returns true if all given arguments are Date-like (have a .getTime() method)

Availability:
Available in MochiKit 1.3.1+

isEmpty(obj[, ...]):

Returns true if all the given Array-like or string arguments are empty (obj.length == 0)

Availability:
Available in MochiKit 1.3.1+

isNotEmpty(obj[, ...]):

Returns true if all the given Array-like or string arguments are not empty (obj.length > 0)

Availability:
Available in MochiKit 1.3.1+

isNull(obj[, ...]):

Returns true if all arguments are null.

Availability:
Available in MochiKit 1.3.1+

isUndefined(obj[, ...]):

Returns true if all arguments are undefined. Note that null values are NOT undefined in JavaScript (use isUndefinedOrNull for that).

Availability:
Available in MochiKit 1.3.1+

isUndefinedOrNull(obj[, ...]):

Returns true if all arguments are undefined or null

Availability:
Available in MochiKit 1.3.1+

isValue(obj[, ...]):

Returns true if all arguments are boolean, number or string values (i.e. basic JavaScript values, not objects or functions).

Availability:
Available in MochiKit 1.5+

itemgetter(name):

Returns a function(obj) that returns obj[name]

Availability:
Available in MochiKit 1.3.1+

items(obj):

Return an Array of [propertyName, propertyValue] pairs for the given obj (in the order determined by for propName in obj).

Availability:
Available in MochiKit 1.3.1+

keyComparator(key[, ...]):

A comparator factory that compares a[key] with b[key]. e.g.:

var lst = ["a", "bbb", "cc"];
lst.sort(keyComparator("length"));
assert( lst.toString() == "a,cc,bbb" );
Availability:
Available in MochiKit 1.3.1+

keys(obj):

Return an Array of the property names of an object (in the order determined by for propName in obj).

Availability:
Available in MochiKit 1.3.1+

listMax(lst):

Return the largest element of an Array-like object, as determined by compare. This is a special form of listMinMax, specifically partial(listMinMax, 1).

Availability:
Available in MochiKit 1.3.1+

listMin(lst):

Return the smallest element of an Array-like object, as determined by compare. This is a special form of listMinMax, specifically partial(listMinMax, -1).

Availability:
Available in MochiKit 1.3.1+

listMinMax(which, lst):

If which == -1 then it will return the smallest element of the Array-like lst. This is also available as listMin(lst).

If which == 1 then it will return the largest element of the Array-like lst. This is also available as listMax(list).

Availability:
Available in MochiKit 1.3.1+

map(fn, lst[, ...]):

Return a new array composed of the results of fn(x) for every x in lst.

If fn is null, and only one sequence argument is given the identity function is used.

map(null, lst) -> lst.slice();

If fn is not null and more than one sequence argument is given, then one element from each sequence is used to build the argument list for fn.

map(fn, p, q, ...)
-> [fn(p[0], q[0], ..), fn(p[1], q[1], ...), ...]

If fn is null, and more than one sequence is given as arguments, then the Array function is used.

map(null, p, q, ...)
-> MochiKit.Iter.zip(p, q, ...) -> [[p0, q0, ...], [p1, q1, ...], ...];

Since this is a common idiom, zip(p, q, ...) is actually a shortcut for this.

Availability:
Available in MochiKit 1.3.1+

mean(lst[, ...]):

Returns the arithmetic mean (average) of the argument list, or an array. This function applies flattenArguments() to the argument list.

Availability:
Available in MochiKit 1.4+

median(lst[, ...]):

Returns the median of the argument list, or an array. This function applies flattenArguments() to the argument list.

Availability:
Available in MochiKit 1.4+

merge(obj[, ...]):

Create a new instance of Object that contains every property from all given objects. If a property is defined on more than one of the objects, the last property is used.

This is a special form of update(self, obj[, ...]), specifically, it is defined as partial(update, null).

Availability:
Available in MochiKit 1.3.1+

method(self, func, ...):

Alternate form of bind that takes the object before the function. These two calls are equivalent:

bind("method", myobject)
method(myobject, "method")
Availability:
Available in MochiKit 1.3.1+

methodcaller(name[, args...]):

Return a new function that calls a method on its argument, for example:

lst = map(methodcaller("toLowerCase"), ["THIS", "is", "LoWeRCaSe"]);
assert( lst.join(" ") == "this is lowercase" );
Availability:
Available in MochiKit 1.4+

module(parent, name, version, deps=[]):

Creates a new name module in a parent namespace. This function will create a new empty module object with NAME, VERSION, toString and __repr__ properties. It will also verify that all the strings in deps are defined in parent, or an error will be thrown.

parent:
The parent module or namespace (object). Use this or window to create a global module.
name:
The new module name.
version:
The module version string, e.g. "1.5".
deps:
The array of module dependencies, as strings.

Example:

module(MochiKit, 'Iter', '1.5', ['Base']);
Availability:
Available in MochiKit 1.5+

moduleExport(namespace, module/*, ...*/):

Exports all symbols from one or more modules into namespace. This is similar to update(self, obj[, ...]), except for special handling of the __export__ flag, contained sub-modules (exported recursively), and names starting with _.

All symbols can be exported to global variables:

MochiKit.Base.moduleExport(this, MochiKit);

Or a few selected modules can be moved to a shortened name:

var dom = MochiKit.Base.moduleExport({}, MochiKit.Dom, MochiKit.Style);
Availability:
Available in MochiKit 1.5+

nameFunctions(namespace):

Given a namespace (object or function) with a NAME property, find all methods in it and give them nice NAME properties too (for use with repr). e.g.:

namespace = {
    NAME: "Awesome",
    Dude: function () {}
}
nameFunctions(namespace);
assert( namespace.Dude.NAME == 'Awesome.Dude' );
Availability:
Available in MochiKit 1.3.1+

noop():

A function that performs no operation. Use this where you would otherwise use (function () {}) in order to avoid Internet Explorer cyclic garbage leakage.

Availability:
Available in MochiKit 1.4

objEqual(a, b):

Return true if compare(a, b) == 0

Availability:
Available in MochiKit 1.3.1+

nodeWalk(node, visitor):

Non-recursive generic node walking function (e.g. for a DOM).

The walk order for nodeWalk is breadth first, meaning that all siblings will be visited before any children.

node:
The initial node to be searched.
visitor:
The visitor function, will be called as visitor(node), and should return an Array-like of nodes to be searched next (e.g. node.childNodes). Leaf nodes may return null or undefined.
Availability:
Available in MochiKit 1.3.1+

objMax(obj[, ...]):

Return the maximum object according to compare out of the given arguments. This is similar to listMax, except is uses the arguments instead of a given Array-like.

Availability:
Available in MochiKit 1.3.1+

objMin(obj[, ...]):

Return the minimum object according to compare out of the given arguments. This is similar to listMin, except it uses the arguments instead of a given Array-like.

Availability:
Available in MochiKit 1.3.1+

operator:

A table of JavaScript's operators for usage with map, filter, etc.

Unary Logic Operators:

Operator Implementation Description
truth(a) !!a Logical truth
lognot(a) !a Logical not
identity(a) a Logical identity

Unary Math Operators:

Operator Implementation Description
not(a) ~a Bitwise not
neg(a) -a Negation

Binary Operators:

Operator Implementation Description
add(a, b) a + b Addition
sub(a, b) a - b Subtraction
div(a, b) a / b Division
mod(a, b) a % b Modulus
mul(a, b) a * b Multiplication
and(a, b) a & b Bitwise and
or(a, b) a | b Bitwise or
xor(a, b) a ^ b Bitwise exclusive or
lshift(a, b) a << b Bitwise left shift
rshift(a, b) a >> b Bitwise signed right shift
zrshift(a, b) a >>> b Bitwise unsigned right shift

Built-in Comparators:

Operator Implementation Description
eq(a, b) a == b Equals
ne(a, b) a != b Not equals
gt(a, b) a > b Greater than
ge(a, b) a >= b Greater than or equal to
lt(a, b) a < b Less than
le(a, b) a <= b Less than or equal to

Strict Built-in Comparators:

Operator Implementation Description
seq(a, b) a === b Strict equals
sne(a, b) a !== b Strict not equals

Extended Comparators (uses compare):

Operator Implementation Description
ceq(a, b) compare(a, b) == 0 Equals
cne(a, b) compare(a, b) != 0 Not equals
cgt(a, b) compare(a, b) == 1 Greater than
cge(a, b) compare(a, b) != -1 Greater than or equal to
clt(a, b) compare(a, b) == -1 Less than
cle(a, b) compare(a, b) != 1 Less than or equal to

Binary Logical Operators:

Operator Implementation Description
logand(a, b) a && b Logical and
logor(a, b) a || b Logical or
contains(a, b) b in a Has property (note order)
Availability:
Available in MochiKit 1.3.1+

parseQueryString(encodedString[, useArrays=false]):

Parse a name=value pair URL query string into an object with a property for each pair. e.g.:

var args = parseQueryString("foo=value%20one&bar=two");
assert( args.foo == "value one" && args.bar == "two" );

If you expect that the query string will reuse the same name, then give true as a second argument, which will use arrays to store the values. e.g.:

var args = parseQueryString("foo=one&foo=two", true);
assert( args.foo[0] == "one" && args.foo[1] == "two" );
Availability:
Available in MochiKit 1.3.1+

partial(func, arg[, ...]):

Return a partially applied function, e.g.:

addNumbers = function (a, b) {
    return a + b;
}

addOne = partial(addNumbers, 1);

assert(addOne(2) == 3);

partial is a special form of bind that does not alter the bound self (if any). It is equivalent to calling:

bind(func, undefined, arg[, ...]);

See the documentation for bind for more details about this facility.

This could be used to implement, but is NOT currying.

Availability:
Available in MochiKit 1.3.1+

queryString(names, values):

Creates a URL query string from a pair of Array-like objects representing names and values. Each name=value pair will be URL encoded by urlEncode. name=value pairs with a value of undefined or null will be skipped. e.g.:

var keys = ["foo", "bar"];
var values = ["value one", "two"];
assert( queryString(keys, values) == "foo=value%20one&bar=two" );
Alternate form 1:
queryString(domElement)

If MochiKit.DOM is loaded, one argument is given, and that argument is either a string or has a nodeType property greater than zero, then names and values will be the result of MochiKit.DOM.formContents(domElement).

Alternate form 2:
queryString({name: value, ...})

Note that when using the alternate form, the order of the name=value pairs in the resultant query string is dependent on how the particular JavaScript implementation handles for (..in..) property enumeration.

When using the second alternate form, name=value pairs with typeof(value) == "function" are ignored. This is a workaround for the case where a poorly designed library has modified Object.prototype and inserted "convenience functions".

Values that are Array-like will be expanded as if they were multiply defined HTML elements. For example:

assert( queryString({a: [1,2]}) === "a=1&a=2" );
Alternate form 2 (MochiKit 1.4+):
queryString([names, values])

This form behaves identically to queryString(names, values), except it takes both arguments as a single Array. This mirrors the return value of MochiKit.DOM.formContents.

Availability:
Available in MochiKit 1.3.1+

registerComparator(name, check, comparator[, override]):

Register a comparator for use with compare.

name:
unique identifier describing the comparator.
check:
function(a, b) that returns true if a and b can be compared with comparator.
comparator:

function(a, b) that returns:

Value Condition
0 a == b
1 a > b
-1 a < b

comparator is guaranteed to only be called if check(a, b) returns a true value.

override:
if true, then this will be made the highest precedence comparator. Otherwise, the lowest.
Availability:
Available in MochiKit 1.3.1+

registerJSON(name, check, simplifier[, override]):

Register a simplifier function for use with serializeJSON.

name:
unique identifier describing the serialization.
check:
function(obj) that returns true if obj can can be simplified for serialization by simplifier.
simplifier:

function(obj) that returns a simpler object that can be further serialized by serializeJSON. For example, you could simplify Date-like objects to ISO 8601 timestamp strings with the following simplifier:

var simplifyDateAsISO = function (obj) {
    return toISOTimestamp(obj, true);
};
registerJSON("DateLike", isDateLike, simplifyDateAsISO);

simplifier is guaranteed to only be called if check(obj) returns a true value.

override:
if true, then this will be made the highest precedence serialization. Otherwise, the lowest.
Availability:
Available in MochiKit 1.3.1+

registerRepr(name, check, wrap[, override]):

Register a programmer representation function. repr functions should take one argument and return a string representation of it suitable for developers, primarily used when debugging.

If override is given, it is used as the highest priority repr, otherwise it will be used as the lowest.

Availability:
Available in MochiKit 1.3.1+

repr(obj):

Return a programmer representation for obj. See the Programmer Representation overview for more information about this function.

Availability:
Available in MochiKit 1.3.1+

reverseKeyComparator(key):

A comparator factory that compares a[key] with b[key] in reverse. e.g.:

var lst = ["a", "bbb", "cc"];
lst.sort(reverseKeyComparator("length"));
assert(lst.toString() == "bbb,cc,a");
Availability:
Available in MochiKit 1.3.1+

serializeJSON(anObject):

Serialize anObject in the JSON [1] format, see JSON Serialization for the coercion rules. For unserializable objects (functions that do not have an adapter, toJSON method, __json__ method, or json method), this will return undefined.

For those familiar with Python, JSON is similar in scope to pickle, but it can not handle recursive object graphs.

Availability:
Available in MochiKit 1.3.1+

setdefault(self, obj[, ...]):

Mutate self by adding all properties from other object(s) that it does not already have set.

If self is null, a new Object instance will be created and returned.

This mutates and returns self, be warned.

Availability:
Available in MochiKit 1.3.1+

typeMatcher(typ[, ...]):

Given a set of types (as string arguments), returns a function(obj[, ...]) that will return true if the types of the given arguments are all members of that set.

Availability:
Available in MochiKit 1.3.1+

update(self, obj[, ...]):

Mutate self by replacing its key:value pairs with those from other object(s). Key:value pairs from later objects will overwrite those from earlier objects.

If self is null, a new Object instance will be created and returned.

This mutates and returns self, be warned.

A version of this function that creates a new object is available as merge(a, b[, ...])

Availability:
Available in MochiKit 1.3.1+

updatetree(self, obj[, ...]):

Mutate self by replacing its key:value pairs with those from other object(s). If a given key has an object value in both self and obj, then this function will be called recursively, updating instead of replacing that object.

If self is null, a new Object instance will be created and returned.

This mutates and returns self, be warned.

Availability:
Available in MochiKit 1.3.1+

urlEncode(unencoded):

Converts unencoded into a URL-encoded string. In this implementation, spaces are converted to %20 instead of "+". e.g.:

assert( URLencode("1+2=2") == "1%2B2%3D2");
Availability:
Available in MochiKit 1.3.1+

values(obj):

Return an Array of the property values of an object (in the order determined by for propName in obj).

Availability:
Available in MochiKit 1.4+

xfilter(fn, obj[, ...]):

Returns a new Array composed of the arguments where fn(obj) returns a true value.

If fn is null, operator.truth will be used.

Availability:
Available in MochiKit 1.3.1+

xmap(fn, obj[, ...):

Return a new Array composed of fn(obj) for every obj given as an argument.

If fn is null, operator.identity is used.

Availability:
Available in MochiKit 1.3.1+

zip(p, q, ...):

Returns an array where the n-th element is an array of the n-th elements from each of the arrays p, q, ...

This is equivalent to calling map(fn, p, q, ...) with null as the first argument.

zip(p, q, ...)
-> map(null, p, q, ...) -> [[p0, q0, ...], [p1, q1, ...], ...];
Availability:
Available in MochiKit 1.3.1+

See Also

[1](1, 2, 3, 4, 5) JSON, JavaScript Object Notation: http://json.org/
[2]Python's itertools module: http://docs.python.org/lib/module-itertools.html

Authors