mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-12 03:47:50 +00:00
Add baseFunctions to ensure _.mixin only iterates over own keys of source objects.
This commit is contained in:
44
lodash.js
44
lodash.js
@@ -1599,6 +1599,30 @@
|
|||||||
return baseForRight(object, callback, keys);
|
return baseForRight(object, callback, keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base implementation of `_.functions` which creates a sorted array of
|
||||||
|
* function property names from those returned by `keysFunc`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} object The object to inspect.
|
||||||
|
* @param {Function} keysFunc The function to get the keys of `object`.
|
||||||
|
* @returns {Array} Returns the new sorted array of property names.
|
||||||
|
*/
|
||||||
|
function baseFunctions(object, keysFunc) {
|
||||||
|
var index = -1,
|
||||||
|
props = keysFunc(object),
|
||||||
|
length = props.length,
|
||||||
|
result = [];
|
||||||
|
|
||||||
|
while (++index < length) {
|
||||||
|
var key = props[index];
|
||||||
|
if (isFunction(object[key])) {
|
||||||
|
result.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.sort();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base implementation of `_.isEqual`, without support for `thisArg`
|
* The base implementation of `_.isEqual`, without support for `thisArg`
|
||||||
* binding, that allows partial "_.where" style comparisons.
|
* binding, that allows partial "_.where" style comparisons.
|
||||||
@@ -6000,7 +6024,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a sorted array of property names of all enumerable function
|
* Creates a sorted array of function property names from all enumerable
|
||||||
* properties, own and inherited, of `object`.
|
* properties, own and inherited, of `object`.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
@@ -6015,14 +6039,7 @@
|
|||||||
* // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
|
* // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
|
||||||
*/
|
*/
|
||||||
function functions(object) {
|
function functions(object) {
|
||||||
var result = [];
|
return baseFunctions(object, keysIn);
|
||||||
|
|
||||||
baseForIn(object, function(value, key) {
|
|
||||||
if (isFunction(value)) {
|
|
||||||
result.push(key);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result.sort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7922,8 +7939,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds function properties of a source object to the destination object.
|
* Adds all own enumerable function properties of a source object to the
|
||||||
* If `object` is a function methods will be added to its prototype as well.
|
* destination object. If `object` is a function methods will be added to
|
||||||
|
* its prototype as well.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
@@ -7955,7 +7973,7 @@
|
|||||||
*/
|
*/
|
||||||
function mixin(object, source, options) {
|
function mixin(object, source, options) {
|
||||||
var chain = true,
|
var chain = true,
|
||||||
methodNames = source && functions(source);
|
methodNames = source && baseFunctions(source, keys);
|
||||||
|
|
||||||
if (!source || (!options && !methodNames.length)) {
|
if (!source || (!options && !methodNames.length)) {
|
||||||
if (options == null) {
|
if (options == null) {
|
||||||
@@ -7963,7 +7981,7 @@
|
|||||||
}
|
}
|
||||||
source = object;
|
source = object;
|
||||||
object = this;
|
object = this;
|
||||||
methodNames = functions(source);
|
methodNames = baseFunctions(source, keys);
|
||||||
}
|
}
|
||||||
if (options === false) {
|
if (options === false) {
|
||||||
chain = false;
|
chain = false;
|
||||||
|
|||||||
33
test/test.js
33
test/test.js
@@ -6383,6 +6383,22 @@
|
|||||||
var value = ['a'],
|
var value = ['a'],
|
||||||
source = { 'a': function(array) { return array[0]; }, 'b': 'B' };
|
source = { 'a': function(array) { return array[0]; }, 'b': 'B' };
|
||||||
|
|
||||||
|
test('should mixin `source` methods into lodash', 4, function() {
|
||||||
|
_.mixin(source);
|
||||||
|
|
||||||
|
strictEqual(_.a(value), 'a');
|
||||||
|
strictEqual(_(value).a().__wrapped__, 'a');
|
||||||
|
|
||||||
|
delete _.a;
|
||||||
|
delete _.prototype.a;
|
||||||
|
|
||||||
|
ok(!('b' in _));
|
||||||
|
ok(!('b' in _.prototype));
|
||||||
|
|
||||||
|
delete _.b;
|
||||||
|
delete _.prototype.b;
|
||||||
|
});
|
||||||
|
|
||||||
test('should use `this` as the default `object` value', 3, function() {
|
test('should use `this` as the default `object` value', 3, function() {
|
||||||
var object = _.create(_);
|
var object = _.create(_);
|
||||||
object.mixin(source);
|
object.mixin(source);
|
||||||
@@ -6425,20 +6441,11 @@
|
|||||||
delete wrapper.prototype.b;
|
delete wrapper.prototype.b;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should mixin `source` methods into lodash', 4, function() {
|
test('should not assign inherited `source` properties', 1, function() {
|
||||||
_.mixin(source);
|
function Foo() {}
|
||||||
|
Foo.prototype = { 'a': _.noop };
|
||||||
|
|
||||||
strictEqual(_.a(value), 'a');
|
deepEqual(_.mixin({}, new Foo, {}), {});
|
||||||
strictEqual(_(value).a().__wrapped__, 'a');
|
|
||||||
|
|
||||||
delete _.a;
|
|
||||||
delete _.prototype.a;
|
|
||||||
|
|
||||||
ok(!('b' in _));
|
|
||||||
ok(!('b' in _.prototype));
|
|
||||||
|
|
||||||
delete _.b;
|
|
||||||
delete _.prototype.b;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should accept an `options` argument', 16, function() {
|
test('should accept an `options` argument', 16, function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user