Skip to content

Instantly share code, notes, and snippets.

@KeithGillette
Last active November 22, 2016 20:05
Show Gist options
  • Save KeithGillette/21df72d67a68c3f7a7af66d1a0b44374 to your computer and use it in GitHub Desktop.
Save KeithGillette/21df72d67a68c3f7a7af66d1a0b44374 to your computer and use it in GitHub Desktop.
/**
* @description Configures an CreateOverrideableArray generator function returning arrays with provided array methods overriden or added
* @param {{ 'functionName': { 'functionToApply': () => any, 'overrideNativeMethod'?: boolean } }} configuration - configuration object
* @returns {function: any[]} CreateOverriddenArray - returns an array of provided parameters with array methods configured
*/
export function ConfigureOverridableArrayFactory(configuration: {}) {
const callingContext = this;
const protoIsSupported = { __proto__: [] } instanceof Array; // Test browser for __proto__ property support
// save all standard array methods in a list
const anArray: any[] = new Array();
let arrayPropertyNameList: string[] = Object.getOwnPropertyNames(Object.getPrototypeOf(anArray));
let arrayMethodList: {} = {};
for (let i = 0; i < arrayPropertyNameList.length; i++) {
if (typeof anArray[arrayPropertyNameList[i]] === 'function' && anArray[arrayPropertyNameList[i]] !== 'constructor') {
arrayMethodList[arrayPropertyNameList[i]] = anArray[arrayPropertyNameList[i]];
}
}
/**
* @description Array generator function returning arrays with provided array methods overriden or added
* @param {...any} arrayElements - optional parameters with which to initialize array prior to application of overridden methods
* @returns {any[]}
*/
function CreateOverriddenArray(...arrayElements: any[]) {
let OverridenArray: any[] = new Array(); // create an array to return whose methods will overridden
OverridenArray.push.apply(OverridenArray, arguments); // push any provided arguments onto the array to return
if (protoIsSupported) { // Change prototype if supported
OverridenArray.__proto__ = CreateOverriddenArray.prototype;
} else { // apply override methods supplied by CreateOverrideableArray on the array instance if we can't put them on the prototype
for (let propertyName in configuration) {
if (arrayPropertyNameList.indexOf(propertyName) !== -1 && configuration[propertyName].overrideNativeMethod) { // override native array method
OverridenArray[propertyName] = function () {
return configuration[propertyName].functionToApply.apply(callingContext, [propertyName, arguments]);
}
} else if (arrayPropertyNameList.indexOf(propertyName) !== -1) { // supplement native array method
OverridenArray[propertyName] = function () {
configuration[propertyName].functionToApply.apply(callingContext, [propertyName, arguments]);
return arrayMethodList[propertyName].apply(this, arguments);
}
} else { // add new array method
OverridenArray[propertyName] = function () {
return configuration[propertyName].functionToApply.apply(callingContext, [propertyName, arguments]);
}
}
}
}
return OverridenArray;
}
if (protoIsSupported) { // if supported, apply override methods supplied by CreateOverrideableArray on prototype for speedier array creation
CreateOverriddenArray.prototype = new Array();
for (let propertyName in configuration) {
if (arrayPropertyNameList.indexOf(propertyName) !== -1 && configuration[propertyName].overrideNativeMethod) { // override native array method
CreateOverriddenArray.prototype[propertyName] = function () {
return configuration[propertyName].functionToApply.apply(callingContext, [propertyName, arguments]);
}
} else if (arrayPropertyNameList.indexOf(propertyName) !== -1) { // supplement native array method
CreateOverriddenArray.prototype[propertyName] = function () {
configuration[propertyName].functionToApply.apply(callingContext, [propertyName, arguments]);
return arrayMethodList[propertyName].apply(this, arguments);
}
} else { // add new array method
CreateOverriddenArray.prototype[propertyName] = function () {
return configuration[propertyName].functionToApply.apply(callingContext, [propertyName, arguments]);
}
}
}
}
return CreateOverriddenArray;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment