Classes
- EmitterList
- Contain and manage a list of @{link OO.EventEmitter} items.
- EventEmitter
- Factory
- Registry
- A map interface for associating arbitrary data with a symbolic name.
- SortedEmitterList
- Manage a sorted list of OO.EmitterList objects.
Methods
(static) binarySearch(arr, searchFunc, forInsertionopt) → {number|null
}
Use binary search to locate an element in a sorted array.
searchFunc is given an element from the array. searchFunc(elem)
must return a number
above 0 if the element we're searching for is to the right of (has a higher index than) elem,
below 0 if it is to the left of elem, or zero if it's equal to elem.
To search for a specific value with a comparator function (a function cmp(a,b)
that returns
above 0 if a > b
, below 0 if a < b
, and 0 if a == b
), you can use
searchFunc = cmp.bind( null, value )
.
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
arr |
Array | Array to search in |
|
searchFunc |
function | Search function |
|
forInsertion |
boolean |
<optional> |
If not found, return index where val could be inserted |
Returns:
Index where val was found, or null if not found
- Type
-
number
|
null
(static) cloneObject(origin) → {Object}
Create a new object that is an instance of the same constructor as the input, inherits from the same object and contains the same own properties.
Create a new object that is an instance of the same constructor as the input, inherits from the same object and contains the same own properties.
This makes a shallow non-recursive copy of own properties. To create a recursive copy of plain objects, use #copy.
var foo = new Person( mom, dad );
foo.setAge( 21 );
var foo2 = OO.cloneObject( foo );
foo.setAge( 22 );
// Then
foo2 !== foo; // true
foo2 instanceof Person; // true
foo2.getAge(); // 21
foo.getAge(); // 22
Parameters:
Name | Type | Description |
---|---|---|
origin |
Object |
Returns:
Clone of origin
- Type
- Object
(static) compare(a, b, asymmetricalopt) → {boolean}
Recursively compare properties between two objects.
A false result may be caused by property inequality or by properties in one object missing from the other. An asymmetrical test may also be performed, which checks only that properties in the first object are present in the second object, but not the inverse.
If either a or b is null or undefined it will be treated as an empty object.
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
a |
Object
|
undefined
|
null
|
First object to compare |
|
b |
Object
|
undefined
|
null
|
Second object to compare |
|
asymmetrical |
boolean |
<optional> |
Whether to check only that a's values are equal to b's (i.e. a is a subset of b) |
Returns:
If the objects contain the same values as each other
- Type
- boolean
(static) copy(source, leafCallbackopt, nodeCallbackopt) → {Object}
Create a plain deep copy of any kind of object.
Copies are deep, and will either be an object or an array depending on source
.
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
source |
Object | Object to copy |
|
leafCallback |
function |
<optional> |
Applied to leaf values after they are cloned but before they are added to the clone |
nodeCallback |
function |
<optional> |
Applied to all values before they are cloned. If the nodeCallback returns a value other than undefined, the returned value is used instead of attempting to clone. |
Returns:
Copy of source object
- Type
- Object
(static) deleteProp(obj, …keysopt)
Delete a deeply nested property of an object using variadic arguments, protecting against undefined property errors, and deleting resulting empty objects.
(static) getHash(val) → {string}
Generate a hash of an object based on its name and data.
Performance optimization: http://jsperf.com/ve-gethash-201208#/toJson_fnReplacerIfAoForElse
To avoid two objects with the same values generating different hashes, we utilize the replacer argument of JSON.stringify and sort the object by key as it's being serialized. This may or may not be the fastest way to do this; we should investigate this further.
Objects and arrays are hashed recursively. When hashing an object that has a .getHash() function, we call that function and use its return value rather than hashing the object ourselves. This allows classes to define custom hashing.
Parameters:
Name | Type | Description |
---|---|---|
val |
Object | Object to generate hash for |
Returns:
Hash of object
- Type
- string
(static) getHash_keySortReplacer(key, val) → {any}
(static) getObjectValues(obj) → {Array}
(static) getProp(obj, …keysopt) → {Object|undefined
}
Get a deeply nested property of an object using variadic arguments, protecting against undefined property errors.
Get a deeply nested property of an object using variadic arguments, protecting against undefined property errors.
quux = OO.getProp( obj, 'foo', 'bar', 'baz' );
is equivalent to quux = obj.foo.bar.baz;
except that the former protects against JS errors if one of the intermediate properties
is undefined. Instead of throwing an error, this function will return undefined in
that case.
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
obj |
Object | ||
keys |
any |
<optional> <repeatable> |
Returns:
obj[arguments[1]][arguments[2]].... or undefined
- Type
-
Object
|
undefined
(static) inheritClass(targetFn, originFn)
Inherit from prototype to another using Object#create.
Beware: This redefines the prototype, call before setting your prototypes.
Beware: This redefines the prototype, can only be called once on a function. If called multiple times on the same function, the previous prototype is lost. This is how prototypal inheritance works, it can only be one straight chain (just like classical inheritance in PHP for example). If you need to work with multiple constructors consider storing an instance of the other constructor in a property instead, or perhaps use a mixin (see OO.mixinClass).
function Thing() {}
Thing.prototype.exists = function () {};
function Person() {
Person.super.apply( this, arguments );
}
OO.inheritClass( Person, Thing );
Person.static.defaultEyeCount = 2;
Person.prototype.walk = function () {};
function Jumper() {
Jumper.super.apply( this, arguments );
}
OO.inheritClass( Jumper, Person );
Jumper.prototype.jump = function () {};
Jumper.static.defaultEyeCount === 2;
var x = new Jumper();
x.jump();
x.walk();
x instanceof Thing && x instanceof Person && x instanceof Jumper;
Parameters:
Name | Type | Description |
---|---|---|
targetFn |
function | |
originFn |
function |
Throws:
-
If target already inherits from origin
- Type
- Error
(static) initClass(fn)
(static) isPlainObject(obj) → {boolean}
(static) isSubClass(testFn, baseFn) → {boolean}
Test whether one class is a subclass of another, without instantiating it.
Every class is considered a subclass of Object and of itself.
Parameters:
Name | Type | Description |
---|---|---|
testFn |
function | The class to be tested |
baseFn |
function | The base class |
Returns:
Whether testFn is a subclass of baseFn (or equal to it)
- Type
- boolean
(static) mixinClass(targetFn, originFn)
Copy over own prototype properties of a mixin.
The 'constructor' (whether implicit or explicit) is not copied over.
This does not create inheritance to the origin. If you need inheritance, use OO.inheritClass instead.
Beware: This can redefine a prototype property, call before setting your prototypes.
Beware: Don't call before OO.inheritClass.
function Foo() {}
function Context() {}
// Avoid repeating this code
function ContextLazyLoad() {}
ContextLazyLoad.prototype.getContext = function () {
if ( !this.context ) {
this.context = new Context();
}
return this.context;
};
function FooBar() {}
OO.inheritClass( FooBar, Foo );
OO.mixinClass( FooBar, ContextLazyLoad );
Parameters:
Name | Type | Description |
---|---|---|
targetFn |
function | |
originFn |
function |
(static) setProp(obj, …keysopt, valueopt)
Set a deeply nested property of an object using variadic arguments, protecting against undefined property errors.
Set a deeply nested property of an object using variadic arguments, protecting against undefined property errors.
OO.setProp( obj, 'foo', 'bar', 'baz' );
is equivalent to obj.foo.bar = baz;
except that
the former protects against JS errors if one of the intermediate properties is
undefined. Instead of throwing an error, undefined intermediate properties will be
initialized to an empty object. If an intermediate property is not an object, or if obj itself
is not an object, this function will silently abort.
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
obj |
Object | ||
keys |
any |
<optional> <repeatable> |
|
value |
any |
<optional> |
(static) simpleArrayDifference(a, b) → {Array}
(static) simpleArrayIntersection(a, b) → {Array}
(static) simpleArrayUnion(…arrays) → {Array}
Compute the union (duplicate-free merge) of a set of arrays.
Arrays values must be convertable to object keys (strings).
By building an object (with the values for keys) in parallel with the array, a new item's existence in the union can be computed faster.
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
arrays |
Array |
<repeatable> |
Arrays to union |
Returns:
Union of the arrays
- Type
- Array