diff --git a/dedupe.js b/dedupe.js index 7d20bdf..f16329f 100644 --- a/dedupe.js +++ b/dedupe.js @@ -1,94 +1,85 @@ -const classNames = (function () { - // don't inherit from Object so we can skip hasOwnProperty check later - // http://stackoverflow.com/questions/15518328/creating-js-object-with-object-createnull#answer-21079232 - function StorageObject() {} - StorageObject.prototype = Object.create(null); - - function _parseArray (resultSet, array) { - const length = array.length; - - for (let i = 0; i < length; ++i) { - _parse(resultSet, array[i]); - } +// Don't inherit from Object so we can skip hasOwnProperty check later. +function StorageObject () {} +StorageObject.prototype = Object.create(null); + +export default function classNames () { + // Don't leak arguments. + // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments + const length = arguments.length; + const args = Array(length); + + for (let i = 0; i < length; i++) { + args[i] = arguments[i]; } - const hasOwn = {}.hasOwnProperty; - - function _parseNumber (resultSet, num) { - resultSet[num] = true; - } + const classSet = new StorageObject(); + appendArray(classSet, args); - function _parseObject (resultSet, object) { - if (object.toString !== Object.prototype.toString && !object.toString.toString().includes('[native code]')) { - resultSet[object.toString()] = true; - return; - } + const list = []; - for (const k in object) { - if (hasOwn.call(object, k)) { - // set value to false instead of deleting it to avoid changing object structure - // https://www.smashingmagazine.com/2012/11/writing-fast-memory-efficient-javascript/#de-referencing-misconceptions - resultSet[k] = !!object[k]; - } + for (const k in classSet) { + if (classSet[k]) { + list.push(k); } } - const SPACE = /\s+/; - function _parseString (resultSet, str) { - const array = str.split(SPACE); - const length = array.length; - - for (let i = 0; i < length; ++i) { - resultSet[array[i]] = true; - } + return list.join(' '); +} + +function appendValue (classSet, arg) { + if (!arg) return; + const argType = typeof arg; + + if (argType === 'string') { + appendString(classSet, arg); + } else if (Array.isArray(arg)) { + appendArray(classSet, arg); + } else if (argType === 'object') { + appendObject(classSet, arg); + } else if (argType === 'number') { + appendNumber(classSet, arg); } +} - function _parse (resultSet, arg) { - if (!arg) return; - const argType = typeof arg; +const SPACE = /\s+/; - // 'foo bar' - if (argType === 'string') { - _parseString(resultSet, arg); +function appendString (classSet, str) { + const array = str.split(SPACE); + const length = array.length; - // ['foo', 'bar', ...] - } else if (Array.isArray(arg)) { - _parseArray(resultSet, arg); + for (let i = 0; i < length; ++i) { + classSet[array[i]] = true; + } +} - // { 'foo': true, ... } - } else if (argType === 'object') { - _parseObject(resultSet, arg); +function appendArray (classSet, array) { + const length = array.length; - // '130' - } else if (argType === 'number') { - _parseNumber(resultSet, arg); - } + for (let i = 0; i < length; ++i) { + appendValue(classSet, array[i]); } +} - function _classNames () { - // don't leak arguments - // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments - const length = arguments.length; - const args = Array(length); - for (let i = 0; i < length; i++) { - args[i] = arguments[i]; - } +function appendNumber (classSet, num) { + classSet[num] = true; +} - const classSet = new StorageObject(); - _parseArray(classSet, args); +const hasOwn = {}.hasOwnProperty; - const list = []; +function appendObject (classSet, object) { + if ( + object.toString !== Object.prototype.toString && + !object.toString.toString().includes('[native code]') + ) { + classSet[object.toString()] = true; + return; + } - for (const k in classSet) { - if (classSet[k]) { - list.push(k) - } + for (const k in object) { + if (hasOwn.call(object, k)) { + // Set value to false instead of deleting it to avoid changing object structure. + // https://www.smashingmagazine.com/2012/11/writing-fast-memory-efficient-javascript/#de-referencing-misconceptions + classSet[k] = !!object[k]; } - - return list.join(' '); } - - return _classNames; -})(); - -export default classNames; +}