milojs/proto

View on GitHub
lib/proto.js

Summary

Maintainability
A
0 mins
Test Coverage
'use strict';


/**
 * Chaining
 * ========
 *
 * `_` can be used to create a wrapped value (object, function, array, etc.) to allow chaining of Proto functions.
 * To unwrap, `_` method of a wrapped value should be used.
 * Usage:
 * ```
 * var arr = _({ 0: 3, 1: 4, 2: 5, length: 3})
 *              .toArray()
 *              .prependArray([1, 2])
 *              .appendArray([6, 7, 8])
 *              ._();
 * ```
 * A wrapped object is an instance of `_` (`Proto` class).
 *
 * Chaining is implemented for development convenience, but it has performance overhead, not only to wrap and unwrap values but in each function call.
 * Although all Proto functions are implemented as methods operating on this and the overhead to redefine them as functions is very small, the overhead to redefine them as methods of wrapped value is slightly higher - chaining is 15-25% slower than using functions (properties of _ that take the first parameter).
 * In cases when performance is critical, you may want to avoid using chaining.
 *
 * @param {Any} self A value to be wrapped
 * @return {Proto}
 */
function Proto(self) {
    // wrap passed parameter in _ object
    var wrapped = Object.create(Proto.prototype);
    wrapped.self = self;
    return wrapped;
};

var funcs = require('./dotjs/functions');
var methods = require('./dotjs/methods');

for (var lib in funcs) {
    var name;
    var libFuncs = funcs[lib];
    var libMethods = methods[lib];
    for (name in libFuncs) {
        Proto[name] = libFuncs[name];
        Proto.prototype[name] = libMethods[name];
    }

    // add constants
    if (lib == 'object')
        for (name in libFuncs._constants)
            Proto[name] = libFuncs._constants[name];
}

Proto.prototype._ = function() {
    return this.self;
};

/**
 * In windows environment, a global `_` value is preserved in `_.underscore`
 */
if (typeof window == 'object') {
    // preserve existing _ object
    if (window._)
        Proto.underscore = window._

    // expose global _ and Proto
    window._ = Proto;
}

if (typeof module == 'object' && module.exports) {
    // export for node/browserify
    module.exports = Proto;
}