mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-09 10:27:49 +00:00
Make _.defaultsDeep and _.merge consistent with _.defaults in assigning undefined values. [closes #2676]
This commit is contained in:
21
lodash.js
21
lodash.js
@@ -2462,7 +2462,7 @@
|
|||||||
*/
|
*/
|
||||||
function assignMergeValue(object, key, value) {
|
function assignMergeValue(object, key, value) {
|
||||||
if ((value !== undefined && !eq(object[key], value)) ||
|
if ((value !== undefined && !eq(object[key], value)) ||
|
||||||
(typeof key == 'number' && value === undefined && !(key in object))) {
|
(value === undefined && !(key in object))) {
|
||||||
baseAssignValue(object, key, value);
|
baseAssignValue(object, key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3616,29 +3616,32 @@
|
|||||||
var isCommon = newValue === undefined;
|
var isCommon = newValue === undefined;
|
||||||
|
|
||||||
if (isCommon) {
|
if (isCommon) {
|
||||||
|
var isArr = isArray(srcValue),
|
||||||
|
isTyped = !isArr && isTypedArray(srcValue);
|
||||||
|
|
||||||
newValue = srcValue;
|
newValue = srcValue;
|
||||||
if (isArray(srcValue) || isTypedArray(srcValue)) {
|
if (isArr || isTyped) {
|
||||||
if (isArray(objValue)) {
|
if (isArray(objValue)) {
|
||||||
newValue = objValue;
|
newValue = objValue;
|
||||||
}
|
}
|
||||||
else if (isArrayLikeObject(objValue)) {
|
else if (isArrayLikeObject(objValue)) {
|
||||||
newValue = copyArray(objValue);
|
newValue = copyArray(objValue);
|
||||||
}
|
}
|
||||||
else {
|
else if (isTyped) {
|
||||||
isCommon = false;
|
isCommon = false;
|
||||||
newValue = baseClone(srcValue, true);
|
newValue = cloneTypedArray(srcValue, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newValue = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
|
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
|
||||||
|
newValue = objValue;
|
||||||
if (isArguments(objValue)) {
|
if (isArguments(objValue)) {
|
||||||
newValue = toPlainObject(objValue);
|
newValue = toPlainObject(objValue);
|
||||||
}
|
}
|
||||||
else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
|
else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
|
||||||
isCommon = false;
|
newValue = initCloneObject(srcValue);
|
||||||
newValue = baseClone(srcValue, true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
newValue = objValue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
47
test/test.js
47
test/test.js
@@ -4512,15 +4512,20 @@
|
|||||||
QUnit.test('should assign source properties if missing on `object`', function(assert) {
|
QUnit.test('should assign source properties if missing on `object`', function(assert) {
|
||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
|
||||||
assert.deepEqual(_.defaults({ 'a': 1 }, { 'a': 2, 'b': 2 }), { 'a': 1, 'b': 2 });
|
var actual = _.defaults({ 'a': 1 }, { 'a': 2, 'b': 2 });
|
||||||
|
assert.deepEqual(actual, { 'a': 1, 'b': 2 });
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('should accept multiple sources', function(assert) {
|
QUnit.test('should accept multiple sources', function(assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
|
||||||
var expected = { 'a': 1, 'b': 2, 'c': 3 };
|
var expected = { 'a': 1, 'b': 2, 'c': 3 },
|
||||||
assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3 }, { 'c': 3 }), expected);
|
actual = _.defaults({ 'a': 1, 'b': 2 }, { 'b': 3 }, { 'c': 3 });
|
||||||
assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 3 }, { 'c': 2 }), expected);
|
|
||||||
|
assert.deepEqual(actual, expected);
|
||||||
|
|
||||||
|
actual = _.defaults({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 3 }, { 'c': 2 });
|
||||||
|
assert.deepEqual(actual, expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('should not overwrite `null` values', function(assert) {
|
QUnit.test('should not overwrite `null` values', function(assert) {
|
||||||
@@ -4537,6 +4542,15 @@
|
|||||||
assert.strictEqual(actual.a, 1);
|
assert.strictEqual(actual.a, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('should assign `undefined` values', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var source = { 'a': undefined, 'b': 1 },
|
||||||
|
actual = _.defaults({}, source);
|
||||||
|
|
||||||
|
assert.deepEqual(actual, { 'a': undefined, 'b': 1 });
|
||||||
|
});
|
||||||
|
|
||||||
QUnit.test('should assign properties that shadow those on `Object.prototype`', function(assert) {
|
QUnit.test('should assign properties that shadow those on `Object.prototype`', function(assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
|
||||||
@@ -4560,8 +4574,11 @@
|
|||||||
'valueOf': 7
|
'valueOf': 7
|
||||||
};
|
};
|
||||||
|
|
||||||
assert.deepEqual(_.defaults({}, source), source);
|
var expected = lodashStable.clone(source);
|
||||||
assert.deepEqual(_.defaults({}, object, source), object);
|
assert.deepEqual(_.defaults({}, source), expected);
|
||||||
|
|
||||||
|
expected = lodashStable.clone(object);
|
||||||
|
assert.deepEqual(_.defaults({}, object, source), expected);
|
||||||
});
|
});
|
||||||
}());
|
}());
|
||||||
|
|
||||||
@@ -4633,6 +4650,16 @@
|
|||||||
assert.strictEqual(actual.a.b, 2);
|
assert.strictEqual(actual.a.b, 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('should assign `undefined` values', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var source = { 'a': undefined, 'b': { 'c': undefined, 'd': 1 } },
|
||||||
|
expected = lodashStable.cloneDeep(source),
|
||||||
|
actual = _.defaultsDeep({}, source);
|
||||||
|
|
||||||
|
assert.deepEqual(actual, expected);
|
||||||
|
});
|
||||||
|
|
||||||
QUnit.test('should merge sources containing circular references', function(assert) {
|
QUnit.test('should merge sources containing circular references', function(assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
|
||||||
@@ -4672,7 +4699,7 @@
|
|||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
|
||||||
var actual = _.defaultsDeep({ 'a': ['abc'] }, { 'a': 'abc' });
|
var actual = _.defaultsDeep({ 'a': ['abc'] }, { 'a': 'abc' });
|
||||||
assert.deepEqual(actual, { 'a': ['abc'] });
|
assert.deepEqual(actual.a, ['abc']);
|
||||||
});
|
});
|
||||||
}());
|
}());
|
||||||
|
|
||||||
@@ -14993,14 +15020,14 @@
|
|||||||
assert.deepEqual(actual, [new Foo(object)]);
|
assert.deepEqual(actual, [new Foo(object)]);
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('should not assign `undefined` values', function(assert) {
|
QUnit.test('should not overwrite existing values with `undefined` values of object sources', function(assert) {
|
||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
|
||||||
var actual = _.merge({ 'a': 1 }, { 'a': undefined, 'b': undefined });
|
var actual = _.merge({ 'a': 1 }, { 'a': undefined, 'b': undefined });
|
||||||
assert.deepEqual(actual, { 'a': 1 });
|
assert.deepEqual(actual, { 'a': 1, 'b': undefined });
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('should skip `undefined` values in array sources if a destination value exists', function(assert) {
|
QUnit.test('should not overwrite existing values with `undefined` values of array sources', function(assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
|
|
||||||
var array = [1];
|
var array = [1];
|
||||||
|
|||||||
Reference in New Issue
Block a user