mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-10 10:57:49 +00:00
Ensure methods accepting a thisArg argument allow null values.
Former-commit-id: 368b943687291f0d7ed02304284ac076ef86e02b
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
'stringClass',
|
'stringClass',
|
||||||
'thisArg',
|
'thisArg',
|
||||||
'toString',
|
'toString',
|
||||||
|
'undefined',
|
||||||
'value',
|
'value',
|
||||||
|
|
||||||
// lesser used variables
|
// lesser used variables
|
||||||
|
|||||||
31
lodash.js
31
lodash.js
@@ -456,8 +456,8 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reusable iterator options shared by
|
* Reusable iterator options shared by
|
||||||
* `every`, `filter`, `find`, `forEach`, `forIn`, `forOwn`, `groupBy`, `map`,
|
* `countBy`, `every`, `filter`, `find`, `forEach`, `forIn`, `forOwn`, `groupBy`,
|
||||||
* `reject`, `some`, and `sortBy`.
|
* `map`, `reject`, `some`, and `sortBy`.
|
||||||
*/
|
*/
|
||||||
var baseIteratorOptions = {
|
var baseIteratorOptions = {
|
||||||
'args': 'collection, callback, thisArg',
|
'args': 'collection, callback, thisArg',
|
||||||
@@ -466,7 +466,7 @@
|
|||||||
'if (!callback) {\n' +
|
'if (!callback) {\n' +
|
||||||
' callback = identity\n' +
|
' callback = identity\n' +
|
||||||
'}\n' +
|
'}\n' +
|
||||||
'else if (thisArg) {\n' +
|
'else if (thisArg !== undefined) {\n' +
|
||||||
' callback = bindIterator(callback, thisArg)\n' +
|
' callback = bindIterator(callback, thisArg)\n' +
|
||||||
'}',
|
'}',
|
||||||
'inLoop': 'if (callback(value, index, collection) === false) return result'
|
'inLoop': 'if (callback(value, index, collection) === false) return result'
|
||||||
@@ -481,7 +481,7 @@
|
|||||||
' var valueProp = callback;\n' +
|
' var valueProp = callback;\n' +
|
||||||
' callback = function(value) { return value[valueProp] }\n' +
|
' callback = function(value) { return value[valueProp] }\n' +
|
||||||
'}\n' +
|
'}\n' +
|
||||||
'else if (thisArg) {\n' +
|
'else if (thisArg !== undefined) {\n' +
|
||||||
' callback = bindIterator(callback, thisArg)\n' +
|
' callback = bindIterator(callback, thisArg)\n' +
|
||||||
'}',
|
'}',
|
||||||
'inLoop':
|
'inLoop':
|
||||||
@@ -516,7 +516,7 @@
|
|||||||
|
|
||||||
/** Reusable iterator options for `find`, `forEach`, `forIn`, and `forOwn` */
|
/** Reusable iterator options for `find`, `forEach`, `forIn`, and `forOwn` */
|
||||||
var forEachIteratorOptions = {
|
var forEachIteratorOptions = {
|
||||||
'top': 'if (thisArg) callback = bindIterator(callback, thisArg)'
|
'top': 'if (thisArg !== undefined) callback = bindIterator(callback, thisArg)'
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Reusable iterator options for `forIn` and `forOwn` */
|
/** Reusable iterator options for `forIn` and `forOwn` */
|
||||||
@@ -549,7 +549,7 @@
|
|||||||
'var isFunc = typeof callback == \'function\';\n' +
|
'var isFunc = typeof callback == \'function\';\n' +
|
||||||
'if (!isFunc) {\n' +
|
'if (!isFunc) {\n' +
|
||||||
' var props = concat.apply(ArrayProto, arguments)\n' +
|
' var props = concat.apply(ArrayProto, arguments)\n' +
|
||||||
'} else if (thisArg) {\n' +
|
'} else if (thisArg !== undefined) {\n' +
|
||||||
' callback = bindIterator(callback, thisArg)\n' +
|
' callback = bindIterator(callback, thisArg)\n' +
|
||||||
'}',
|
'}',
|
||||||
'inLoop':
|
'inLoop':
|
||||||
@@ -792,7 +792,7 @@
|
|||||||
'arrayLikeClasses, ArrayProto, bind, bindIterator, compareAscending, concat, ' +
|
'arrayLikeClasses, ArrayProto, bind, bindIterator, compareAscending, concat, ' +
|
||||||
'forIn, hasOwnProperty, identity, indexOf, isArguments, isArray, isFunction, ' +
|
'forIn, hasOwnProperty, identity, indexOf, isArguments, isArray, isFunction, ' +
|
||||||
'isPlainObject, objectClass, objectTypes, nativeKeys, propertyIsEnumerable, ' +
|
'isPlainObject, objectClass, objectTypes, nativeKeys, propertyIsEnumerable, ' +
|
||||||
'slice, stringClass, toString',
|
'slice, stringClass, toString, undefined',
|
||||||
'var callee = function(' + args + ') {\n' + iteratorTemplate(data) + '\n};\n' +
|
'var callee = function(' + args + ') {\n' + iteratorTemplate(data) + '\n};\n' +
|
||||||
'return callee'
|
'return callee'
|
||||||
);
|
);
|
||||||
@@ -1862,7 +1862,7 @@
|
|||||||
' if (prop in object) result[prop] = object[prop]\n' +
|
' if (prop in object) result[prop] = object[prop]\n' +
|
||||||
' }\n' +
|
' }\n' +
|
||||||
'} else {\n' +
|
'} else {\n' +
|
||||||
' if (thisArg) callback = bindIterator(callback, thisArg)',
|
' if (thisArg !== undefined) callback = bindIterator(callback, thisArg)',
|
||||||
'inLoop':
|
'inLoop':
|
||||||
'if (callback(value, index, object)) result[index] = value',
|
'if (callback(value, index, object)) result[index] = value',
|
||||||
'bottom': '}'
|
'bottom': '}'
|
||||||
@@ -2184,7 +2184,7 @@
|
|||||||
'init': 'accumulator',
|
'init': 'accumulator',
|
||||||
'top':
|
'top':
|
||||||
'var noaccum = arguments.length < 3;\n' +
|
'var noaccum = arguments.length < 3;\n' +
|
||||||
'if (thisArg) callback = bindIterator(callback, thisArg)',
|
'if (thisArg !== undefined) callback = bindIterator(callback, thisArg)',
|
||||||
'beforeLoop': {
|
'beforeLoop': {
|
||||||
'array': 'if (noaccum) result = iteratee[++index]'
|
'array': 'if (noaccum) result = iteratee[++index]'
|
||||||
},
|
},
|
||||||
@@ -2763,7 +2763,7 @@
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (thisArg) {
|
if (thisArg !== undefined) {
|
||||||
callback = bindIterator(callback, thisArg);
|
callback = bindIterator(callback, thisArg);
|
||||||
}
|
}
|
||||||
while (++index < length) {
|
while (++index < length) {
|
||||||
@@ -2813,7 +2813,7 @@
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (thisArg) {
|
if (thisArg !== undefined) {
|
||||||
callback = bindIterator(callback, thisArg);
|
callback = bindIterator(callback, thisArg);
|
||||||
}
|
}
|
||||||
while (++index < length) {
|
while (++index < length) {
|
||||||
@@ -3011,7 +3011,7 @@
|
|||||||
high = array.length;
|
high = array.length;
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
if (thisArg) {
|
if (thisArg !== undefined) {
|
||||||
callback = bind(callback, thisArg);
|
callback = bind(callback, thisArg);
|
||||||
}
|
}
|
||||||
value = callback(value);
|
value = callback(value);
|
||||||
@@ -3105,7 +3105,7 @@
|
|||||||
}
|
}
|
||||||
if (!callback) {
|
if (!callback) {
|
||||||
callback = identity;
|
callback = identity;
|
||||||
} else if (thisArg) {
|
} else if (thisArg !== undefined) {
|
||||||
callback = bindIterator(callback, thisArg);
|
callback = bindIterator(callback, thisArg);
|
||||||
}
|
}
|
||||||
while (++index < length) {
|
while (++index < length) {
|
||||||
@@ -3954,10 +3954,11 @@
|
|||||||
* // => also calls `mage.castSpell(n)` three times
|
* // => also calls `mage.castSpell(n)` three times
|
||||||
*/
|
*/
|
||||||
function times(n, callback, thisArg) {
|
function times(n, callback, thisArg) {
|
||||||
|
n = +n || 0;
|
||||||
var index = -1,
|
var index = -1,
|
||||||
result = Array(n || 0);
|
result = Array(n);
|
||||||
|
|
||||||
if (thisArg) {
|
if (thisArg !== undefined) {
|
||||||
while (++index < n) {
|
while (++index < n) {
|
||||||
result[index] = callback.call(thisArg, index);
|
result[index] = callback.call(thisArg, index);
|
||||||
}
|
}
|
||||||
|
|||||||
56
test/test.js
56
test/test.js
@@ -1713,7 +1713,61 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ok(pass, methodName + ' allows falsey arguments');
|
ok(pass, '_.' + methodName + ' allows falsey arguments');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should handle `null` `thisArg` arguments', function() {
|
||||||
|
var thisArg,
|
||||||
|
array = ['a'],
|
||||||
|
callback = function() { thisArg = this; },
|
||||||
|
useStrict = Function('"use strict";return this')() === undefined;
|
||||||
|
|
||||||
|
var funcs = [
|
||||||
|
'countBy',
|
||||||
|
'every',
|
||||||
|
'filter',
|
||||||
|
'find',
|
||||||
|
'forEach',
|
||||||
|
'forIn',
|
||||||
|
'forOwn',
|
||||||
|
'groupBy',
|
||||||
|
'map',
|
||||||
|
'max',
|
||||||
|
'min',
|
||||||
|
'omit',
|
||||||
|
'pick',
|
||||||
|
'reduce',
|
||||||
|
'reduceRight',
|
||||||
|
'reject',
|
||||||
|
'some',
|
||||||
|
'sortBy',
|
||||||
|
'sortedIndex',
|
||||||
|
'times',
|
||||||
|
'uniq'
|
||||||
|
];
|
||||||
|
|
||||||
|
_.each(funcs, function(methodName) {
|
||||||
|
var func = _[methodName],
|
||||||
|
message = '_.' + methodName + ' handles `null` `thisArg` arguments';
|
||||||
|
|
||||||
|
thisArg = undefined;
|
||||||
|
|
||||||
|
if (/^reduce/.test(methodName)) {
|
||||||
|
func(array, callback, 0, null);
|
||||||
|
} else if (methodName == 'sortedIndex') {
|
||||||
|
func(array, 'a', callback, null);
|
||||||
|
} else if (methodName == 'times') {
|
||||||
|
func(1, callback, null);
|
||||||
|
} else {
|
||||||
|
func(array, callback, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useStrict) {
|
||||||
|
deepEqual(thisArg, null, message);
|
||||||
|
} else {
|
||||||
|
equal(thisArg, window, message);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}());
|
}());
|
||||||
|
|||||||
Reference in New Issue
Block a user