UsefulJS Core

The core provides basic utility functions and properties that are used by the rest of the library.

Properties

These are the public properties available under the UsefulJS namespace:

globalObject

The global context; may be one of window or global.

globalObjectName

The name of the global context; may be one of "window" or "global".

RE_WS

Regular expression object to test for whitespace. In most modern browsers this will be equivalent to /\s/

However, not all browsers correctly make \s Unicode-aware. RE_WS is Unicode-aware and may be used to correctly test for whitespace in all browsers:

UsefulJS.RE_WS.test("\u00a0"); // true

RE_WS_START

Portable regular expression object that matches whitespace at the start of a string.

RE_WS_END

Portable regular expression object that matches whitespace at the end of a string.

featureSupport

A map of detected features. This is intended primarily for internal use and currently exposes the following properties that your application code can test for:

Additional modules (such as ClassList) may add additional properties.

UsefulJS does a minimum amount of feature detection. Use something like Modernizr if you want a full-featured library for detecting HTML5 and CSS3 support.

listSeparator

The detected list separator (such as ',' or ';') in use on the system.

Methods

These are the public methods available under the UsefulJS namespace:

defined

Tests to see whether its argument is defined, that is not null or undefined

Syntax
UsefulJS.defined(obj)
Usage
// Optional boolean parameter defaults to true
var f = function(strParam, boolParam) {
    if (!UsefulJS.defined(boolParam)) {
        boolParam = true;
    }
    ...
};

_typeof

Returns somewhat more reliable run-time type information for its argument than the built-in typeof operator.

Syntax
UsefulJS._typeof(obj)
Description

Poor RTTI is one of JavaScript's core weaknesses and makes generic programming painful and error prone. Almost everything is identified as an "object":

typeof("a")             // "string"; OK
typeof([])              // "array";  Good
// Pre-allocate
typeof(new Array(1000)) // "object"; Huh?
typeof(null)            // "object"; You're kidding, right?
typeof(document)        // "object"; A pattern emerges

_typeof uses introspection (not duck-typing, other than as a last resort) to identify the type of its argument:

_typeof(new Array(1000)) // "array"
_typeof(null)            // "null"
_typeof(document)        // "document"

A list of inputs and return values is shown below:

InputReturn value InputReturn value
undefined"undefined" User-defined class"object"
null"null" Date"date"
Boolean"boolean" RegExp"regexp"
new Boolean()"boolean" ArrayBuffer"arraybuffer"
Number"number" Element (any)"element"
new Number()"number" Element attribute"attr"
String"string" Text node"text"
new String()"string" document"document"
Array"array" Event (any)"event"
new Array()"array" Error (any)"error"
Function"function" window"window"
new Function()"function" Math"math"
Object"object" JSON"json"
Element, event and error objects are identified generically as "element", "event" and "error" respectively, regardless of their particular type. It is more useful to identify an HTML element object generically than specifically as, for example, an "htmldivelement".
Usage
var addClass = function(elem, clName) {
    // Inputs must be an element and a string
    var _u = UsefulJS;
    if (!(_u._typeof(elem) === "element" &&
        _u._typeof(clName) === "string")) {
        throw new TypeError("Bad arguments");
    }
    ...
};

clone

Returns an object that is equal but not identical to its argument

Syntax
UsefulJS.clone(obj)
Description

JavaScript Array and Object variables are pointers. Not keeping this in mind can lead to hard-to-track-down bugs:

var a = [1, 2, 3, 4], b = a;
... Many lines later ...
b[0] = 5;       // Changed a; is this intended?

clone creates, in effect, a bitwise copy of its argument, resulting in an independent copy that can safely be modified without unexpected side-effects:

var a = [1, 2, 3, 4], b = UsefulJS.clone(a);
... Many lines later ...
b[0] = 5;       // a[0] is still 1

Only objects for which cloning makes sense are cloned; other types are returned as-is. Cloneable object types are:

Arrays and Objects are cloned recursively, that is any cloneable items that they contain are also cloned.

clone keeps track of how many times it has been called recursively in a single clone operation. If the recursion depth exceeds 100, it will raise an Error. This is better than a browser crash. Basically, if your Objects contain circular references by design, (this may be legitimate in a tree structure, for example) do not attempt to clone them. If your Objects contain circular references by accident, give yourself a smack on the head!
If the browser does not support Object.create, cloning an instance of a user-defined class will cause the returned value to lose its identity: the properties will be copied, but it will no longer be an instance of the class. You can test UsefulJS.featureSupport.createObject to see whether instances of a user-defined class can be successfully cloned.

To clarify the results of a clone operation, examine the following snippet:

var a = { a : 1, b : [1] }, b = UsefulJS.clone(a);
a.a === b.a;                    // scalar, true
a.b === b.b;                    // array, false
a.b[0] === b.b[0];              // true
a === b;                        // false
Usage
var StaticList = function(arr) {
    // Hide the initial data in a closure
    this.data = (function() {
        var _data = UsefulJS.clone(arr);

        return {
            get : function() {
                // Don't give out private data
                return UsefulJS.clone(_data);
            }
        };
    })();
};

var sl = new StaticList([1, 2, 3, 4]), arr = sl.data.get();
arr[0] = 2;
var k = sl.data.get()[0];  // k = 1;
defined, _typeof and clone are exported to the global namespace by default. _typeof is intended as a drop-in replacement for the built-in typeof operator. Apart from UsefulJS itself, these are the only additions to the global namespace.

pad

Pads a string to a specified length using a specified character; padding is either left or right

Syntax
UsefulJS.pad(s, padTo, padWith, right)
Parameters

Returns: String

Usage
// Turn a string into a series of \uxxxx sequences
var uLit = Array.from("한국어").reduce(function(s, c) {
    return s + "\\u" + UsefulJS.pad(c.charCodeAt(0).toString(16), 4, '0');
}, "");
The UsefulJS.String module optionally makes padLeft and padRight methods of String.prototype

mix

Merges properties from one object into another.

Syntax
UsefulJS.mix(o1, o2, prefer1)
Parameters

Returns: Object

Description

Copies the properties that are in o2 into o1 and returns o1. o2 is unaffected.

To avoid inadvertent bugs with shared references, properties are cloned rather than copied.

If both o2 and o1 have identically named properties that are also Objects, the two values will be mixed recursively.

The prefer1 parameter controls how conflicts are handled. If o1 already contains a property and prefer1 is true, it will be left alone (unless it is an Object - see above). Otherwise it will be overwritten.

Usage
var a = {
    a : 1,
    b : {
        p1 : "a"
    },
    d : null
}, b = {
    a : 2,
    b : {
        p1 : "b",
        p2 : "c"
    },
    c : 3,
    d : 4
};
UsefulJS.mix(a, b, true);
// a is now
// {
//     a : 1,
//     b : {
//         p1 : "a",
//         p2 : "c"
//     },
//     c : 3,
//     d : null
// }
The mix function is used when defining locale properties. Each locale definition contains only the attributes that are different from another locale and these are mixed with the properties of the parent locale.

keys

Returns the property names (or keys) of an Object

Syntax
UsefulJS.keys(obj)
Parameters

Returns: Array of property names. If the object has no enumerable properties, the array will be empty.

Description

This will be the same function as Object.keys if that function is implemented. The return value only contains property names for which hasOwnProperty returns true.

every

Iterates over an object, calling a callback function for each enumerable property until either the keys are exhausted or the callback function returns false.

Syntax
UsefulJS.every(obj, callback, ctx)
Parameters

Returns: Boolean true unless the callback returns false.

Throws: TypeError if the callback is not a function.

filter

Iterates over an object, calling a callback function for each enumerable property which should return true for the properties that are to be copied into the return value.

Syntax
UsefulJS.filter(obj, callback, ctx)
Parameters

All iteration functions take the same parameters

Returns: Object A shallow copy of the input with a subset of the properties of the original.

find

Iterates over an object, calling a callback function for each enumerable property which should return true if the required value has been found.

Syntax
UsefulJS.find(obj, callback, ctx)
Parameters

All iteration functions take the same parameters

Returns: Object The item that satisfies the callback or undefined.

findKey

Iterates over an object, calling a callback function for each enumerable property which should return true if the required key has been found.

Syntax
UsefulJS.findKey(obj, callback, ctx)
Parameters

All iteration functions take the same parameters

Returns: Object The key that satisfies the callback or undefined.

forEach

Iterates over an object, calling a callback function for each enumerable property.

Syntax
UsefulJS.forEach(obj, callback, ctx)
Parameters

All iteration functions take the same parameters

Returns: undefined.

map

Iterates over an object, calling a callback function for each enumerable property which should return a value be set in the return value. The property name set will be the same one passed to the callback

Syntax
UsefulJS.map(obj, callback, ctx)
Parameters

All iteration functions take the same parameters

Returns: Object A shallow copy of the input with the same property names as the original but with values transformed by the mapping function.

some

Iterates over an object, calling a callback function for each enumerable property until either the keys are exhausted or the callback function returns true.

Syntax
UsefulJS.some(obj, callback, ctx)
Parameters

All iteration functions take the same parameters

Returns: Boolean false unless the callback returns true.

Usage
var _u = UsefulJS, obj = { ... };
// Does the object have any undefined values
var isGood = _u.every(obj, function(item, key) {
    return _u.defined(item);
});

// Filter out undefined values
obj = isGood ? obj : _u.filter(obj, function(item, key) {
    return _u.defined(item);
});

// Transform the values remaining
obj = _u.map(obj, function(item, key) {
    return String(item).toLocaleUpperCase();
});
Notes

Many objects, such as strings and instances of Date or RegExp, have no enumerable properties.

The properties that will be enumerated over are frozen when you call an iterator. This means that you can modify the input (it's passed as the obj parameter to the callback) as it's iterated over. The callback will not be called for properties that are no longer in the input.

You can pass Array objects to the iteration functions and the return value from filter and map will be arrays. However, since Array objects have their own iteration methods which, likely as not, will run at native speed, there is little point.

Array-like objects are better served with generic Array methods. For example, Array.prototype.forEach will iterate over the characters in a string while UsefulJS.forEach will not.

filter creates a shallow copy of the input. Be careful with shared references. Depending on how values are transformed, the return value from map may have shared references as well.

If the system supports Object.create, the returns from filter and map will be the instances of the same class as the input. Otherwise they will be plain objects.

uuid

Generates a UUID (universally unique identifier).

Syntax
UsefulJS.uuid()
Description

Generates an RFC 4122-compliant UUID. The version field is 4 (randomly generated).

fix

Applies fixes provided by the various UsefulJS modules

Syntax
UsefulJS.fix(opts)
Description

Each UsefulJS module registers fix callbacks with the core on load. When you call UsefulJS.fix, these callbacks are called and the fixes are applied. You can control which fixes are applied via the (optional) opts parameter. If you are happy with the defaults, you don't need to specify anything. If, for some reason, you don't want the defined function exported into the global namespace, you'd call fix like this:

UsefulJS.fix({
    _core : {
        defined : false
    }
});

Rather than supplying Objects as the input options, you can specify "all" or "none". So if you didn't want anything exported into the global namespace you could call:

UsefulJS.fix({
    _core : "none"
});

The return value is an object indicating which fixes have been applied. The naming convention in the output properties is the same as that in the input properties so that if the defaults are used, the output properties might look like this:

{
    _core : {
        defined : true,
        _typeof : true,
        clone : true
    },
    _array : {
        ...
    }
    ...
}
Remember, fixes are not applied when they are not needed. If they are not applied, there won't be anything in the return value relating to them. So on Internet Explorer 8, for example, the _array property in the return value will be populated while on Internet Explorer 9, it won't be.

Generally, fixes that fill in standard methods and properties that are absent in the runtime environment are applied by default and have to be explicitly disabled. Non-standard extensions to the standard classes have to be explicitly enabled.

fromCodePoint

Implementation of String.fromCodePoint.

Syntax
UsefulJS.fromCodePoint(codePoint1[, codePoint2, ...])
Description

If String.fromCodePoint is implemented in the browser, this will be the same function. It constructs a String from one or more code points (numeric values between 0 and 0x10ffff). Code points between 0x10000 and 0x10ffff are resolved into surrogate pairs.

codePointAt

Implementation of String.prototype.codePointAt.

Syntax
UsefulJS.codePointAt.call(str, pos)
Description

If String.prototype.codePointAt is implemented in the browser, this will be the same function. It behaves like charCodeAt unless the character at pos is one half of a surrogate pair, in which case it combines the character code at this position and the next into a single value >= 0x10000.

is

Implementation of Object.is.

Syntax
UsefulJS.is(a, b)
Description

Evaluates to the same boolean value as a === b with two exceptions: returns false if a is 0 and b is -0 (or vice versa); returns true if a and b are both NaN.

Fixes

The fixes for the core module are defined in the _core namespace in the input and output properties. All are applied by default.

defined

Make UsefulJS.defined available in the global namespace.

_typeof

Make UsefulJS._typeof available in the global namespace.

clone

Make UsefulJS.clone available in the global namespace.

language

Add navigator.language property if not already present.

On Firefox and Internet Explorer (after the fix is applied anyway) navigator.language contains a value that you can use. On Webkit-based browsers, the value is baked in at compile-time and is consequently useless.

bindFunction

Adds a bind method to Function.prototype if not already present.

is

Adds an "is" static method to Object if not already present.