Classified is a collection of native extensions and useful modules. It is built using Classify, but you don't really need to use the Classify syntax to use the features of Classified.

Features

  • A complete list of reliable type checking functions.
  • Extends String with inflection methods from Rails, including pluralize & singularize.
  • Includes an Enumerable module, a great Ruby-inspired collection of methods for iteration.
  • Provides an Events module for adding Event binding & triggering to any Javascript object.

Source

The project is hosted on Github. You can report bugs and propose features on the issues page.

Downloads

Usage

Usage is pretty simple. Include the latest compatible version of Classify and the Classified library on your page and your all set.

<script src="/javascripts/classify.min.js" type="text/javascript"></script>
<script src="/javascripts/classified.min.js" type="text/javascript"></script>

I package them separately because I'm on the Head.js bandwagon now. So this is my preferred method for loading:

<script src="/javascripts/head.js" type="text/javascript"></script>
<body>
  <script type="text/javascript">
    head.js(
      "/javascripts/classify.min.js",
      "/javascripts/classified.min.js",
      // my libs
    );
  </script>
</body>

Other than that, familiarize yourself with available method extensions and the provided modules and you're all set.

Array

.slice Array.slice(array, start, end)

Calls Array.prototype.slice on the given array. Convenience method for slicing & cloning arrays. Useful for turning arguments into an array.

function method() {
  return Array.slice(arguments);
}
method(1, 2, 3); // [ 1, 2, 3 ]

#clear array.clear()

Clears the array (makes it empty) and returns the array reference.

var array = [ 1, 2, 3 ];
array.clear(); // []

#clone array.clone()

Returns a duplicate of the array, leaving the original array intact.

var array1 = [ 1, 2, 3 ];
var array2 = array1.clone();
array2.push(4);
// array1 equals [ 1, 2, 3 ]
// array2 equals [ 1, 2, 3, 4 ]

#compact array.compact()

Returns a copy of the array without any null or undefined values.

var array = [ 1, null, 2 ];
array[4] = 3; // [ 1, null, 2, undefined, 3 ]
array.compact(); // [ 1, 2, 3 ]

#first array.first()

Convenience method for returning the array's first object.

var array = [ 1, 2, 3 ];
array.first(); // 1

#flatten array.flatten()

Returns a flattened (one-dimensional) copy of the array, leaving the original array unchanged.

var array = [ 1, 2, [ 3, 4 ] ];
array.flatten(); [ 1, 2, 3, 4 ]

#isBlank array.isBlank()

Checks if the array is empty or only contains null objects.

var array = [];
array[2] = null;
array.isBlank(); // true
array[2] = false;
array.isBlank(); // false

#isEmpty array.isEmpty()

Checks if the array is empty (has a length of zero);

var array = [];
array.isEmpty(); // true
array.push(1);
array.isEmpty(); // false

#indexOf array.indexOf(object, offset)

Returns the index of the first occurrence of object within the array, or -1 if object doesn't exist in the array. It compares objects using strict equality (===). If available, the native Array#indexOf method will be used.

var array = [ 1, 2, 2, 3 ];
array.indexOf(2); // 1
array.indexOf(5); // -1

#last array.last()

Convenience method for returning the array's last object.

var array = [ 1, 2, 3 ];
array.last(); // 3

#lastIndexOf array.lastIndexOf(object)

Returns the position of the last occurrence of object within the array, or -1 if object doesn't exist in the array. If available, the native Array#lastIndexOf method will be used.

var array = [ 1, 2, 2, 3 ];
array.lastIndexOf(2); // 2
array.lastIndexOf(5); // -1

#remove array.remove(object)

Removes the first instance of object from the array. If object is found and removed, it will be returned. Otherwise, undefined will be returned.

var array = [ 1, 2, 3, 2 ];
array.remove(2); // 2
// array equals [ 1, 3, 2 ]
array.remove(5); // undefined

#removeAll array.removeAll(object)

Removes all instances of the object from the array. If object is found and removed, it will be returned. Otherwise, undefined will be returned.

var array = [ 1, 2, 3, 2 ];
array.removeAll(2); // 2
// array equals [ 1, 3 ]
array.removeAll(5); // undefined

#removeAt array.removeAt(index)

Removes the object at the specified index. If an object is found and removed, it will be returned. Otherwise, undefined will be returned.

var array = [ 1, 2, 3 ];
array.removeAt(1); // 2
// array equals [ 1, 3 ]
array.removeAt(5); // undefined

#uniq array.uniq(sorted)

Produces a duplicate-free version of an array. If no duplicates are found, the original array is returned.

On large arrays when sorted is false, this method has a potentially large performance cost.

var array = [ 1, 2, 2, 2, 3 ];
array.uniq(true); // [ 1, 2, 3 ]
array = [ 3, 2, 2, 1, 2 ];
array.uniq(false); // [ 3, 2, 1 ] (very slow on large arrays)

Enumerable

Enumerable is a collection of methods for iterating over objects. Enumerable is included in Array by default, but can easily be added to other objects by implementing an __each__ method.

Implementing __each__

__each__ should loop through the objects within the object's collection and pass them to the given iterator. For instance, this is how it is implemented in Array:

Array.prototype.__each__ = function(iterator) {
  for (var i = 0; i < this.length; i++) {
    iterator(this[i]);
  }
};

And here's a simple example of how to implement it in a vanilla object:

var object = {
  __each__ : function(iterator) {
    for (var property in this) {
      iterator([ property, this[property] ]);
    }
  }
};

Including Enumerable

To include the Enumerable methods, use the include method provided by Classify.

classify('Hash', function() {
  include(Enumerable);

  def('__each__', function(iterator) {
    // iterate here.
  });
});

Iterator Context

Every Enumerable method takes a context argument (usually the last) that defines what the value of this will be within the iterator.

var array = [ 1, 2, 3 ];
var amount = 0;
array.each(function(value) {
  this += value;
}, amount); // sets `amount` as the `context`
// amount now equal 6

#each enumerable#each(iterator, context)

Calls iterator for each object in the collection. Setting context will set the value of this within the iterator.

var array = [ 1, 2, 3 ];
var sum = 0;
array.each(function(value) {
  this += vlaue;
}, sum);
// sum now equals 6

#all enumerable#all(iterator, context)

Calls iterator for each object in the collection. The method returns true if all iterations return a truthy value. If no iterator is given, an implicit identity iterator is used (function(element) { return element; }).

Aliased as every.

[ 'ant', 'bear', 'cat' ].all(function(word){
  return word.length >= 3;
});
// => true
[ 'ant', 'bear', 'cat' ].all(function(word){
  return word.length >= 4;
});
// => false
[ null, true, 99 ].all();
// => false

#any enumerable#any(iterator, context)

Calls iterator for each object in the collection. The method returns true if any iteration returns a truthy value. If no iterator is given, an implicit identity iterator is used (function(element) { return element; }).

Aliased as some.

[ 'ant', 'bear', 'cat' ].any(function(word){
  return word.length >= 4;
});
// => true
[ 'ant', 'bear', 'cat' ].any(function(word){
  return word.length >= 5;
});
// => false
[ null, true, 99 ].any();
// => true

#collect enumerable#collect(iterator, context)

Returns a new array with the results of running iterator once for every object in the collection.

Aliased as map.

[ 1, 2, 3, 4 ].collect(function(i) {
  return i * i;
});
// => [ 1, 4, 9, 16 ]
[ 1, 2, 3, 4 ].collect(function(i) {
  return 'cat';
});
// => [ 'cat', 'cat', 'cat', 'cat' ]

#detect enumerable#detect(iterator, context)

Calls iterator for each object in the collection. Returns the first object for which the iterator returns a truthy value. If no object matches, it returns null.

Aliased as find.

[ 1, 2, -3, 4, -5 ].detect(function(n) {
  return n < 0;
});
// => -3
[ 1, 2, 3, 4, 5 ].detect(function(n) {
  return n < 0;
});
// => null

#include enumerable#include(object)

Determines whether a given object is in the collection or not, based on the == comparison operator (equality with implicit type conversion).

Aliased as contains.

[ 1, 2, 3, 4, 5 ].include(3);
// => true
[ 1, 2, 3, 4, 5 ].include(0);
// => false

#inject enumerable#inject(memo, iterator, context)

Incrementally builds a result value based on the successive results of the iterator. This can be used for array construction, numerical sums/averages, etc.

The iterator function is called once for each object in the enumeration, receiving the current value of the memo as its first argument, the object as its second argument, and the object's index as its third. It returns the new value for the memo.

Aliased as reduce.

[ 1, 2, 3, 4, 5 ].inject(0, function(result, n) {
  return result + n;
});
// => 15

#invoke enumerable#invoke(method, ...arguments)

Invokes the same method, with the same arguments, for all objects in a collection. Returns an array of the results of the method calls.

[ 'hello', 'world' ].invoke('toUpperCase');
// => [ 'HELLO', 'WORLD' ]
[ 'hello', 'world' ].invoke('substring', 0, 3);
// => [ 'hel', 'wor' ]

#pluck enumerable#pluck(property)

Pre-baked implementation for a common use-case of Enumerable#collect and Enumerable#each: fetching the same property for all of the objects in the collection. Returns an array of the property values.

[ 'hello', 'world', 'this', 'is', 'nice' ].pluck('length');
// => [ 5, 5, 4, 2, 4 ]

#reject enumerable#reject(iterator, context)

Returns all the objects in the collection for which the iterator returns a falsy value. For the opposite operation, see Enumerable#select.

Aliased as not.

[ 1, 'two', 3, 'four', 5 ].reject(Object.isString);
// => [ 1, 3, 5 ]

#select enumerable#select(property)

Returns all the objects in the collection for which the iterator returns a truthy value. For the opposite operation, see Enumerable#reject.

Aliased as findAll & filter.

[ 1, 'two', 3, 'four', 5 ].select(Object.isString);
// => [ 'two', 'four' ]

Events

Events is a collection of methods for event binding and triggering modeled after the jQuery Events API. It can easily be added to any class or existing object.

Including Events

To include the Events methods in a class, use the include method provided by Classify.

classify('Hash', function() {
  include(Events);
});

var hash = new Hash();
hash.bind('event', function() {});
hash.trigger('event');

Extending Objects

To extend existing objects, use the extend method provided by Classify.

var object = {};
extend(object, Events);

// now can use Events
object.bind('event', function() {});
object.trigger('event');

#bind events#bind(type, handler)

Bind an event, specified by a string name, type, to a handler function.

object.bind('event', function() {
  alert('Event triggered!')
});
object.trigger('event');
// Alerts 'Event Triggered!'

Passing 'all' will bind the handler to all events fired.

object.bind('all', function() {
  alert('Event triggered!')
});
object.trigger('event');
// Alerts 'Event Triggered!'

#unbind events#unbind([type[, handler]])

Remove one or many events.

var handler = function() {
  alert('Event Triggered!');
};
object.bind('event', handler);
object.unbind('event', handler);
object.trigger('event');
// no alert...

If handler is null, removes all events for the event.

object.bind('event', function() {
  alert('Event Triggered!');
});
object.bind('event', function() {
  alert('Another Alert!');
});
object.unbind('event');
object.trigger('event');
// no alerts...

If no arguments are given, all event handlers will be removed.

object.bind('event', function() {
  alert('Event Triggered!');
});
object.bind('anotherEvent', function() {
  alert('Another Event Triggered!');
});
object.unbind();
object.trigger('event');
object.trigger('anotherEvent');
// no alerts...

#trigger events#trigger(type, ...arguments)

Trigger an event, firing all bound events. Callbacks are passed the same arguments as trigger is, apart from the event name.

object.bind('event', function() {
  alert(Array.slice(arguments));
});
object.trigger('event', 1, 2, 3);
// Alerts `[1, 2, 3]`

Listening for 'all' passes the true event name as the first argument.

object.bind('all', function() {
  alert(Array.slice(arguments));
});
object.trigger('event', 1, 2, 3);
// Alerts `['event', 1, 2, 3]`

Function

#bind function.bind(context, ...arguments)

Binds the function to the given context by wrapping it in another function and returning the wrapper. Whenever the resulting "bound" function is called, it will call the original ensuring that this is set to context. Also optionally curries arguments for the function.

var amount = 5;
function add(value) { return this + value; }
var addToAmount = add.bind(amount);
addToAmount(10); // 15

var addTwentyToAmount = add.bind(amount, 20);
addTwentyToAmount(); // 35

#curry function.curry(...arguments)

Curries (burns in) arguments to a function, returning a new function that when called with call the original passing in the curried arguments (along with any new ones):

function showArguments() {
  return Array.slice(arguments);
}
var curried = showArguments(1, 2, 3);
curried();     // [ 1, 2, 3 ]
curried(4, 5); // [ 1, 2, 3, 4, 5 ]

#defer function.defer(timeout, ...arguments)

Schedules the function to run as soon as the interpreter is idle. Calling stop will stop the function from being executed. Also returns an integer ID that can be used to clear the timeout with window.clearTimeout.

alert('1');
alert.defer('2');
alert('3');
// Alerts '1' then '3' then '2'

#delay function.delay(timeout, ...arguments)

Schedules the function to run after the specified amount of time (in seconds), passing any arguments given. Calling stop will stop the function from being executed. Also returns an integer ID that can be used to clear the timeout with window.clearTimeout.

alert.delay(0.5, 'Hello World');
// After half a second 'Hello World' will be alerted.

#periodical function.periodical(timeout, ...arguments)

Executes a function in the specified intervals of time (in seconds), passing any arguments given. Calling stop will stop the function from being executed. Also returns an integer ID that can be used to clear the timeout with window.clearInterval.

alert.periodical(1, 'This will be annoying');
// Alerts 'This will be annoying' every second

#stop function.stop()

If a delay, defer, or periodical call has been made, calling stop will stop the function from executing by clearing any timeouts or intervals.

alert.delay(0.5, 'Hello World');
alert.stop(); // 'Hello World' is never alerted.

alert.periodical(1, 'This will be annoying');
alert.stop(); // Saves the day

Number

#times number.times(iterator, context)

Calls iterator the specified number of times, passing in a number as the first parameter. The number will be 0 on first call, 1 on second call, etc. times returns the number instance it was called on.

(3).times(alert);
// Alerts `0`, `1`, then `2`

var count = 0;
(10).times(function() {
  count += 10;
}, count);
// count is 100

Object

.isArray Object.isArray(object)

Returns true if object is an array. If available, the native Array.isArray function will be used.

Object.isArray(null); // false
Object.isArray({}); // false
Object.isArray([]); // true

.isBoolean Object.isBoolean(object)

Returns true if object is a boolean. This does not evaluate the object as if it is boolean.

Object.isBoolean(); // false
Object.isBoolean({}); // false
Object.isBoolean(true); // true

.isDate Object.isDate(object)

Returns true if object is a date.

Object.isDate(0); // false
Object.isDate(new Date()); // true

.isDefined Object.isDefined(object)

Returns false if object is undefined. Because checking if objects are undefined or not is so common, Classified adds isDefined as a convenience method.

var object = { 'foo' : null };
Object.isDefined(); // false
Object.isDefined(object); // true
Object.isDefined(object.foo); // true
Object.isDefined(object.bar); // false

.isFunction Object.isBoolean(object)

Returns true if object is a function.

function noop() { }

Object.isFunction({}); // false
Object.isFunction(noop); // true

.isNumber Object.isNumber(object)

Returns true if object is a number.

Object.isNumber('0'); // false
Object.isNumber(0); // true

.isObject Object.isObject(object)

Returns true if object is an object. Native types like Array & Date, which normally return 'object' when using typeof actually return false using isObject. Custom class instances will always return true.

function Class() { }

Object.isObject(null); // false
Object.isObject({}); // true
Object.isObject([]); // false
Object.isObject(new Date()); // false
Object.isObject(new Class()); // true

.isRegExp Object.isRegExp(object)

Returns true if object is a regular expression.

Object.isRegExp('asdf'); // false
Object.isRegExp(/asdf/); // true

.isString Object.isString(object)

Returns true if object is a string.

Object.isString(/asdf/); // false
Object.isString('asdf'); // true

.isUndefined Object.isUndefined(object)

Returns true if object is undefined.

var object = { 'foo' : null };
Object.isUndefined(); // true
Object.isUndefined(object); // false
Object.isUndefined(object.foo); // false
Object.isUndefined(object.bar); // true

.all Object.all(object, iterator, context)

Returns true if each value in object satisfies the provided iterator function. The iterator function will be passed 2 arguments, the name of the property and the value of the property. Setting context will set the value of this within the iterator.

var object = { 'foo' : 5, 'bar' : 12 };
var equalFive = function(key, value) { return value == 5; };
Object.all(object, equalFive); // false
object.bar = 5;
Object.all(object, equalFive); // true

.any Object.any(object, iterator, context)

Returns true if at least one value in object satisfies the provided iterator function. The iterator function will be passed 2 arguments, the name of the property and the value of the property. Setting context will set the value of this within the iterator.

var object = { 'foo' : 5, 'bar' : 12 };
var equalFive = function(key, value) { return value == 5; };
Object.any(object, equalFive); // true
object.foo = 12;
Object.any(object, equalFive); // false

.clone Object.clone(object)

Creates and returns a shallow duplicate of object by copying all of the original's properties onto an empty object. This is a shallow copy, not a deep copy. Nested objects will retain their references. Also, note this creates plain objects and does not clone class instances.

var object = { 'foo' : 1 };
var clone = Object.clone(object); // { 'foo' : 1 }
object === clone; // false

.each Object.each(object, iterator, context)

Loops through all the properties of a object. The iterator function will be passed 2 arguments, the name of the property and the value of the property. Setting context will set the value of this within the iterator.

var object = { 'foo' : 1, 'bar' : 2 };
Object.each(object, function(key, value) {
  this[key] = value + 10;
}, object);
// object is now { 'foo' : 11, 'bar' : 12 }

.extend Object.extend(object, extension)

Copies all properties from extension to object. Aliased as merge.

var object = { 'foo' : 1 };
Object.extend(object, { 'bar' : 2 }); // { 'foo' : 1, 'bar' : 2 }
Object.extend(object, null); // { 'foo' : 1, 'bar' : 2 }

.include Object.include(object, value)

Tests for the presence of a value in object.

var object = { 'foo' : 5, 'bar' : 12 };
Object.include(object, 0); // false
Object.include(object, 5); // true

.keys Object.keys(object)

Returns an array of the property names from object. If available, the native Object.keys method will be used.

var object = { 'foo' : 5, 'bar' : 12 };
Object.keys(object); // [ 'foo', 'bar' ]

.values Object.values(object)

Returns an array of the property values from object.

var object = { 'foo' : 5, 'bar' : 12 };
Object.values(object); // [ 5, 12 ]

RegExp

.escape RegExp.escape(string)

Escapes any characters in the string that have special meaning in a regular expression. Use before passing a string into the RegExp constructor.

var escaped = RegExp.escape('animals.sheep[1]'); // 'animals\.sheep\[1\]'
// now this will work as expected
new RegExp(escaped).test('animals.sheep[1]'); // true

String

#camelize string.camelize()

Converts a string separated by dashes or underscores into a camel case equivalent.

'foo_bar'.camelize();       // 'fooBar'
'border-bottom'.camelize(); // 'borderBottom'

#capitalize string.capitalize()

Capitalizes the first letter of a string. Leaves the rest of the string unchanged.

'hello'.capitalize(); // 'Hello'
'HELLO'.capitalize(); // 'HELLO'

#constantize string.constantize()

Tries to find a constant with the name specified. The name is assumed to be the one of a top-level constant.

window.namespace = { 'Class' : function() { } };

'String'.constantize();          // String
'namespace.Class'.constantize(); // namespace.Class
'namespace.Blank'.constantize(); // undefined

#dasherize string.dasherize()

Converts a camelized string into a series of lowercase words separated by an dash ('-'). Also replaces underscores '_' with dashes.

'border_bottom_width'.dasherize(); // 'border-bottom-width'
'borderBottom'.dasherize();        // 'border-bottom'

#endsWith string.endsWith(string)

Checks if the string ends with the given string.

'hello'.endsWith('lo'); // true
'hey'.endsWith('lo');   // false

#humanize string.humanize()

Capitalizes the first word and turns underscores and dashes into spaces.

'foo_bar'.humanize();             // 'Foo bar'
'border-bottom-width'.humanize(); // 'Border bottom width'

#include string.include(string)

Checks if the string contains the given string.

Aliased as contains().

'foo bar'.include('foo'); // true
'bar'.include('foo');     // false

#isBlank string.isBlank()

Check if the string is either empty (length of 0) or contains only whitespace.

''.isBlank();        // true
'   '.isBlank();     // true
'foo bar'.isBlank(); // false

#isEmpty string.isEmpty()

Check if the string is either empty (length of 0).

''.isEmpty();        // true
'   '.isEmpty();     // false
'foo bar'.isEmpty(); // false

#pluralize string.pluralize()

Returns the string with the last word converted to its plural form.

'post'.pluralize()         // 'posts'
'octopus'.pluralize()      // 'octopi'
'sheep'.pluralize()        // 'sheep'
'words'.pluralize()        // 'words'
'CamelOctopus'.pluralize() // 'CamelOctopi'

#singularize string.singularize()

Returns the string with the last word converted to its singular form.

'posts'.singularize()       // 'post'
'octopi'.singularize()      // 'octopus'
'sheep'.singularize()       // 'sheep'
'words'.singularize()       // 'words'
'CamelOctopi'.singularize() // 'CamelOctopus'

#startsWith string.startsWith(string)

Checks if the string starts with the given string.

'hello'.startsWith('hel'); // true
'hey'.startsWith('hel');   // false

#strip string.strip()

Removes all leading and trailing whitespace from a string.

'     hello    '.strip();  // 'hello'
'\r\ngoodbye\r\n'.strip(); // 'goodbye'

#titleize string.titleize()

Capitalizes all the words and replaces some characters in the string to create a nicer looking title.

Aliased as toTitleCase().

'man from the boondocks'.titleize() // 'Man From The Boondocks'
'x-men: the last stand'.titleize()  // 'X Men: The Last Stand'

#underscore string.underscore()

Converts a camelized string into a series of words separated by an underscore ('_'). Also replaces dashes '-' with underscores.

'border-bottom-width'.dasherize(); // 'border_bottom_width'
'borderBottom'.dasherize();        // 'border_bottom'

Changelog

0.5.7 Jan. 4, 2011

Fixed a Array.slice bug in IE.

0.5.6 Dec. 15, 2010

Added Object.isBoolean type checking method.

0.5.5 Dec. 15, 2010

Adding Object.all, Object.any, and Object.include methods.

0.5.4 Dec. 13, 2010

Adding Inflector module with a bunch of built-in inflections. Also added pluralize(), singularize(), and constantize() to String.

0.5.3 Dec. 10, 2010

Added Object.isRegExp type checking method.

0.5.2 Dec. 8, 2010

Added type checking methods to Object. Added Array.slice as a convenience method. Also added Object.keys and Object.values.

0.5.1 Nov. 30, 2010

Added a bunch of methods to Function, including curry(), delay(), defer(), periodical(), and stop().

0.5.0 Nov. 29, 2010

Removed Hash class. String#capitalize no longer lowercases after the first letter. Number now includes all of the functions from Math as well as times() for iteration. Added pluck() and invoke() to Enumerable. Added clone(), removeAt(), remove(), removeAll, isEmpty(),isBlank(), andflatten() to Array.

0.4.0 Nov. 27, 2010

Added Events module.

0.3.1 Nov. 24, 2010

Added Object.clone.

0.3.0 Nov. 17, 2010

Added Hash class. Added Object.extend. Added abs(), ceil(), floor(), and round() to Number. Added endsWith(), startsWith(), include(), isBlank(), isEmpty(), and strip() to String.