mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-09 10:27:49 +00:00
Simplify iteratorTemplate.
This commit is contained in:
211
dist/lodash.compat.js
vendored
211
dist/lodash.compat.js
vendored
@@ -126,21 +126,6 @@
|
||||
'writable': false
|
||||
};
|
||||
|
||||
/** Used as the data object for `iteratorTemplate` */
|
||||
var iteratorData = {
|
||||
'args': '',
|
||||
'array': null,
|
||||
'bottom': '',
|
||||
'firstArg': '',
|
||||
'init': '',
|
||||
'keys': null,
|
||||
'loop': '',
|
||||
'shadowedProps': null,
|
||||
'support': null,
|
||||
'top': '',
|
||||
'useHas': false
|
||||
};
|
||||
|
||||
/** Used to determine if values are of the language type Object */
|
||||
var objectTypes = {
|
||||
'boolean': false,
|
||||
@@ -892,91 +877,58 @@
|
||||
*/
|
||||
var iteratorTemplate = function(obj) {
|
||||
|
||||
var __p = 'var index, iterable = ' +
|
||||
(obj.firstArg) +
|
||||
', result = ' +
|
||||
var __p = 'var result = ' +
|
||||
(obj.init) +
|
||||
';\nif (!iterable) return result;\n' +
|
||||
';\nif (!(object && objectTypes[typeof object])) return result;\n' +
|
||||
(obj.top) +
|
||||
';';
|
||||
if (obj.array) {
|
||||
__p += '\nvar length = iterable.length; index = -1;\nif (' +
|
||||
(obj.array) +
|
||||
') { ';
|
||||
if (support.unindexedChars) {
|
||||
__p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } ';
|
||||
}
|
||||
__p += '\n while (++index < length) {\n ' +
|
||||
if (support.nonEnumArgs) {
|
||||
__p += '\nvar length = object.length;\nif (length && isArguments(object)) {\n key = -1;\n while (++key < length) {\n key += \'\';\n ' +
|
||||
(obj.loop) +
|
||||
';\n }\n}\nelse { ';
|
||||
} else if (support.nonEnumArgs) {
|
||||
__p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' +
|
||||
(obj.loop) +
|
||||
';\n }\n } else { ';
|
||||
';\n }\n return result\n}';
|
||||
}
|
||||
|
||||
if (support.enumPrototypes) {
|
||||
__p += '\n var skipProto = typeof iterable == \'function\';\n ';
|
||||
__p += '\nvar skipProto = typeof object == \'function\';\n';
|
||||
}
|
||||
|
||||
if (support.enumErrorProps) {
|
||||
__p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n ';
|
||||
__p += '\nvar skipErrorProps = object === errorProto || object instanceof Error;\n';
|
||||
}
|
||||
|
||||
var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); }
|
||||
|
||||
if (obj.useHas && obj.keys) {
|
||||
__p += '\n var ownIndex = -1,\n ownProps = keys(iterable),\n length = ownProps.length;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n';
|
||||
if (conditions.length) {
|
||||
var conditions = [];
|
||||
if (support.enumPrototypes) { conditions.push('!(skipProto && key == \'prototype\')'); }
|
||||
if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (key == \'message\' || key == \'name\'))'); }
|
||||
__p += '\nfor (var key in object) {\n';
|
||||
if (obj.useHas) { conditions.push('hasOwnProperty.call(object, key)'); }
|
||||
if (conditions.length) {
|
||||
__p += ' if (' +
|
||||
(conditions.join(' && ')) +
|
||||
') {\n ';
|
||||
}
|
||||
__p +=
|
||||
(obj.loop) +
|
||||
'; ';
|
||||
'; ';
|
||||
if (conditions.length) {
|
||||
__p += '\n }';
|
||||
}
|
||||
__p += '\n } ';
|
||||
} else {
|
||||
__p += '\n for (index in iterable) {\n';
|
||||
if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) {
|
||||
__p += ' if (' +
|
||||
(conditions.join(' && ')) +
|
||||
') {\n ';
|
||||
}
|
||||
__p +=
|
||||
(obj.loop) +
|
||||
'; ';
|
||||
if (conditions.length) {
|
||||
__p += '\n }';
|
||||
}
|
||||
__p += '\n } ';
|
||||
__p += '\n}\n';
|
||||
if (support.nonEnumShadows) {
|
||||
__p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n ';
|
||||
for (k = 0; k < 7; k++) {
|
||||
__p += '\n index = \'' +
|
||||
(obj.shadowedProps[k]) +
|
||||
'\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))';
|
||||
if (!obj.useHas) {
|
||||
__p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])';
|
||||
__p += '\nif (object !== objectProto) {\n var ctor = object.constructor,\n isProto = object === (ctor && ctor.prototype),\n className = object === stringProto ? stringClass : object === errorProto ? errorClass : toString.call(object),\n nonEnum = nonEnumProps[className];\n ';
|
||||
for (var index = 0; index < 7; index++) {
|
||||
__p += '\n key = \'' +
|
||||
(obj.shadowedProps[index]) +
|
||||
'\';\n if ((!(isProto && nonEnum[key]) && hasOwnProperty.call(object, key))';
|
||||
if (!obj.useHas) {
|
||||
__p += ' || (!nonEnum[key] && object[key] !== objectProto[key])';
|
||||
}
|
||||
__p += ') {\n ' +
|
||||
__p += ') {\n ' +
|
||||
(obj.loop) +
|
||||
';\n } ';
|
||||
';\n } ';
|
||||
}
|
||||
__p += '\n } ';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (obj.array || support.nonEnumArgs) {
|
||||
__p += '\n}';
|
||||
}
|
||||
__p +=
|
||||
(obj.bottom) +
|
||||
';\nreturn result';
|
||||
__p += '\nreturn result';
|
||||
|
||||
return __p
|
||||
};
|
||||
@@ -1285,6 +1237,40 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates `arguments` objects, arrays, objects, and strings consistently
|
||||
* across environments, executing the callback for each element in the
|
||||
* collection. The callback is bound to `thisArg` and invoked with three
|
||||
* arguments; (value, index|key, collection). Callbacks may exit iteration
|
||||
* early by explicitly returning `false`.
|
||||
*
|
||||
* @private
|
||||
* @param {Array|Object|string} collection The collection to iterate over.
|
||||
* @param {Function} [callback=identity] The function called per iteration.
|
||||
* @param {*} [thisArg] The `this` binding of `callback`.
|
||||
* @returns {Array|Object|string} Returns `collection`.
|
||||
*/
|
||||
function baseEach(collection, callback, thisArg) {
|
||||
var index = -1,
|
||||
iterable = collection,
|
||||
length = collection ? collection.length : 0;
|
||||
|
||||
callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
|
||||
if (typeof length == 'number') {
|
||||
if (support.unindexedChars && isString(iterable)) {
|
||||
iterable = iterable.split('');
|
||||
}
|
||||
while (++index < length) {
|
||||
if (callback(iterable[index], index, collection) === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
forOwn(collection, callback);
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.flatten` without support for callback
|
||||
* shorthands or `thisArg` binding.
|
||||
@@ -1741,47 +1727,27 @@
|
||||
* Creates compiled iteration functions.
|
||||
*
|
||||
* @private
|
||||
* @param {...Object} [options] The compile options object(s).
|
||||
* @param {string} [options.array] Code to determine if the iterable is an array or array-like.
|
||||
* @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop.
|
||||
* @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration.
|
||||
* @param {Object} [options] The compile options object.
|
||||
* @param {string} [options.args] A comma separated string of iteration function arguments.
|
||||
* @param {string} [options.top] Code to execute before the iteration branches.
|
||||
* @param {string} [options.loop] Code to execute in the object loop.
|
||||
* @param {string} [options.bottom] Code to execute after the iteration branches.
|
||||
* @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop.
|
||||
* @returns {Function} Returns the compiled function.
|
||||
*/
|
||||
function createIterator() {
|
||||
// data properties
|
||||
iteratorData.shadowedProps = shadowedProps;
|
||||
|
||||
// iterator options
|
||||
iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = '';
|
||||
iteratorData.init = 'iterable';
|
||||
iteratorData.useHas = true;
|
||||
|
||||
// merge options into a template data object
|
||||
for (var object, index = 0; object = arguments[index]; index++) {
|
||||
for (var key in object) {
|
||||
iteratorData[key] = object[key];
|
||||
}
|
||||
}
|
||||
var args = iteratorData.args;
|
||||
iteratorData.firstArg = /^[^,]+/.exec(args)[0];
|
||||
function createIterator(options) {
|
||||
options.shadowedProps = shadowedProps;
|
||||
|
||||
// create the function factory
|
||||
var factory = Function(
|
||||
'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' +
|
||||
'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' +
|
||||
'objectTypes, nonEnumProps, stringClass, stringProto, toString',
|
||||
'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}'
|
||||
'baseCreateCallback, errorClass, errorProto, hasOwnProperty, isArguments, ' +
|
||||
'objectProto, objectTypes, nonEnumProps, stringClass, stringProto, toString',
|
||||
'return function(' + options.args + ') {\n' + iteratorTemplate(options) + '\n}'
|
||||
);
|
||||
|
||||
// return the compiled function
|
||||
return factory(
|
||||
baseCreateCallback, errorClass, errorProto, hasOwnProperty,
|
||||
indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto,
|
||||
objectTypes, nonEnumProps, stringClass, stringProto, toString
|
||||
baseCreateCallback, errorClass, errorProto, hasOwnProperty, isArguments,
|
||||
objectProto, objectTypes, nonEnumProps, stringClass, stringProto, toString
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1948,7 +1914,8 @@
|
||||
'args': 'object',
|
||||
'init': '[]',
|
||||
'top': 'if (!(objectTypes[typeof object])) return result',
|
||||
'loop': 'result.push(index)'
|
||||
'loop': 'result.push(key)',
|
||||
'useHas': true
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -1975,15 +1942,6 @@
|
||||
return nativeKeys(object);
|
||||
};
|
||||
|
||||
/** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
|
||||
var eachIteratorOptions = {
|
||||
'args': 'collection, callback, thisArg',
|
||||
'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)",
|
||||
'array': "typeof length == 'number'",
|
||||
'keys': keys,
|
||||
'loop': 'if (callback(iterable[index], index, collection) === false) return result'
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to convert characters to HTML entities:
|
||||
*
|
||||
@@ -2007,22 +1965,6 @@
|
||||
var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
|
||||
reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
|
||||
|
||||
/**
|
||||
* A function compiled to iterate `arguments` objects, arrays, objects, and
|
||||
* strings consistenly across environments, executing the callback for each
|
||||
* element in the collection. The callback is bound to `thisArg` and invoked
|
||||
* with three arguments; (value, index|key, collection). Callbacks may exit
|
||||
* iteration early by explicitly returning `false`.
|
||||
*
|
||||
* @private
|
||||
* @type Function
|
||||
* @param {Array|Object|string} collection The collection to iterate over.
|
||||
* @param {Function} [callback=identity] The function called per iteration.
|
||||
* @param {*} [thisArg] The `this` binding of `callback`.
|
||||
* @returns {Array|Object|string} Returns `collection`.
|
||||
*/
|
||||
var baseEach = createIterator(eachIteratorOptions);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
@@ -2034,7 +1976,6 @@
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @type Function
|
||||
* @alias extend
|
||||
* @category Objects
|
||||
* @param {Object} object The destination object.
|
||||
@@ -2220,7 +2161,6 @@
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @type Function
|
||||
* @category Objects
|
||||
* @param {Object} object The destination object.
|
||||
* @param {...Object} [source] The source objects.
|
||||
@@ -2393,9 +2333,11 @@
|
||||
* });
|
||||
* // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
|
||||
*/
|
||||
var forIn = createIterator(eachIteratorOptions, {
|
||||
'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
|
||||
'array': false,
|
||||
var forIn = createIterator({
|
||||
'args': 'object, callback, thisArg',
|
||||
'init': 'object',
|
||||
'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)",
|
||||
'loop': 'if (callback(object[key], key, object) === false) return result',
|
||||
'useHas': false
|
||||
});
|
||||
|
||||
@@ -2452,7 +2394,6 @@
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @type Function
|
||||
* @category Objects
|
||||
* @param {Object} object The object to iterate over.
|
||||
* @param {Function} [callback=identity] The function called per iteration.
|
||||
@@ -3751,7 +3692,7 @@
|
||||
} else if (support.unindexedChars && isString(collection)) {
|
||||
iterable = collection.split('');
|
||||
}
|
||||
baseEach(collection, function(value, key, collection) {
|
||||
baseEach(iterable, function(value, key) {
|
||||
key = props ? props[--length] : --length;
|
||||
return callback(iterable[key], key, collection);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user