-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathobject.js
90 lines (81 loc) · 2.87 KB
/
object.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/* 深克隆 deepClone */
const deepClone = obj => {
let clone = Object.assign({}, obj)
Object.keys(clone).forEach(
key => (clone[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key])
)
return Array.isArray(obj) ? (clone.length = obj.length) && Array.from(clone) : clone
}
const a = { foo: 'bar', obj: { a: 1, b: 2 } };
const b = deepClone(a); // a !== b, a.obj !== b.obj
/* 深冻结 */
const deepFreeze = obj =>
Object.keys(obj).forEach(
prop =>
!(obj[prop] instanceof Object) || Object.isFrozen(obj[prop]) ? null : deepFreeze(obj[prop])
) || Object.freeze(obj);
'use strict';
const o = deepFreeze([1, [2, 3]]);
o[0] = 3; // not allowed
o[1][0] = 4; // not allowed as well
/* 深判断相等 Performs a deep comparison between two values to determine if they are equivalent. */
const equals = (a, b) => {
if (a === b) return true
if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime()
if (!a || !b (typeof a !== 'object' && typeof b !== 'object')) return a === b
if (a === null || a === undefined || b === null || b === undefined) return false
if (a.prototype !== b.prototype) return false
let keys = Object.keys(a)
if (keys.length !== Object.keys(b).length) return false
return keys.every(k => equals(a[k], b[k]))
}
equals({ a: [2, { e: 3 }], b: [4], c: 'foo' }, { a: [2, { e: 3 }], b: [4], c: 'foo' }); // true
/* 平铺展开对象 */
const flattenObject = (obj, prefix = '') =>
Object.keys(obj).reduce((acc, k) => {
const pre = prefix.length ? prefix + '.' : '';
if (typeof obj[k] === 'object') Object.assign(acc, flattenObject(obj[k], pre + k));
else acc[pre + k] = obj[k];
return acc;
}, {});
console.log(flattenObject({ a: { b: { c: 1 } }, d: 1 })) // { 'a.b.c': 1, d: 1 })
/* 改写对象key为小写 */
// reduce 声明少一个变量
const lowercaseKeys = obj =>
Object.keys(obj).reduce((acc, key) => {
acc[key.toLowerCase()] = obj[key];
return acc;
}, {});
const myObj = { Name: 'Adam', sUrnAME: 'Smith' };
const myObjLower = lowercaseKeys(myObj); // {name: 'Adam', surname: 'Smith'};
/* 抽出对象中某个键值对 */
const mapValues = (obj, fn) =>
Object.keys(obj).reduce((acc, k) => {
acc[k] = fn(obj[k], k, obj);
return acc;
}, {});
const users = {
fred: { user: 'fred', age: 40 },
pebbles: { user: 'pebbles', age: 1 }
};
mapValues(users, u => u.age); // { fred: 40, pebbles: 1 }
/* 两个对象软合并 不减少对象中的键值对*/
const merge = (...objs) =>
[...objs].reduce(
(acc, obj) =>
Object.keys(obj).reduce((a, k) => {
acc[k] = acc.hasOwnProperty(k) ? [].concat(acc[k]).concat(obj[k]) : obj[k];
return acc;
}, {}),
{}
);
const object = {
a: [{ x: 2 }, { y: 4 }],
b: 1
};
const other = {
a: { z: 3 },
b: [2, 3],
c: 'foo'
};
merge(object, other); // { a: [ { x: 2 }, { y: 4 }, { z: 3 } ], b: [ 1, 2, 3 ], c: 'foo' }