我正在寻找除了null
之外还能覆盖undefined
值的Lodash的defaults
和defaultsDeep
版本。我看过defaultsDeep
的源代码,但找不到一种简单的方法来让它工作。我宁愿使用一个简单的解决方案,可能基于Lodash,而不是使用我自己的解决方案。
发布于 2018-06-09 12:35:34
可以通过使用lodash#mergeWith
合并对象,并以lodash#isNil
作为识别条件来确定变量是null
还是undefined
,从而解决此问题。
// Note: if you change `_.isNil` to `_.isUndefined`
// then you'd get the `_.defaults()` normal behavior
const nilMerge = (a, b) => _.isNil(a)? b: a;
const nilMergeDeep = (a, b) => (_.isObject(a) && !_.isArray(a))
// recursively merge objects with nilMergeDeep customizer
? _.mergeWith({}, a, b, nilMergeDeep)
// let's use our default customizer
: nilMerge(a, b);
// defaults not deep with null/undefined
const result1 = _.mergeWith({}, o1, o2, o3, nilMerge);
// defaults deep with null/undefined
const result2 = _.mergeWith({}, o1, o2, o3, nilMergeDeep);
const o1 = {
a: 1,
b: 2,
c: 3,
d: null,
x: {
x1: 1,
x2: 2,
x3: null
},
z: null
};
const o2 = {
a: 9999,
d: 4,
e: null,
f: 123,
x: {
x3: 3,
x4: null
},
z: ['a', 'b']
};
const o3 = {
b: 9999,
e: 5,
f: 2,
g: 234,
x: {
x4: 4,
x5: 5,
x6: ['hi', 'there']
},
z: ['c']
};
// Note: if you change `_.isNil` to `_.isUndefined`
// then you'd get the `_.defaults()` normal behavior
const nilMerge = (a, b) => _.isNil(a)? b: a;
const nilMergeDeep = (a, b) => (_.isObject(a) && !_.isArray(a))
// recursively merge objects with nilMergeDeep customizer
? _.mergeWith({}, a, b, nilMergeDeep)
// let's use our default customizer
: nilMerge(a, b);
// defaults not deep with null/undefined
const result1 = _.mergeWith({}, o1, o2, o3, nilMerge);
// defaults deep with null/undefined
const result2 = _.mergeWith({}, o1, o2, o3, nilMergeDeep);
console.log('defaults not deep with null/undefined');
console.log(result1);
console.log('defaults deep with null/undefined');
console.log(result2);
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
发布于 2018-06-08 20:18:44
https://stackoverflow.com/questions/50692777
复制相似问题