limu
Version:
A fast js lib of immutable data, based on shallow copy on read and mark modified on write mechanism
87 lines (86 loc) • 2.26 kB
JavaScript
import { isMap, isObject, isPrimitive, isSet } from '../support/util';
export function deepCopy(obj) {
const innerDeep = (obj) => {
if (isPrimitive(obj)) {
return obj;
}
// TODO: 或许这里通过 metaVer 能够解决多引用问题 ( see 3.4.2 )
// TODO: 传入参数 reuse,确定是否走逻辑查看 meta.modified,并复用 meta.copy or meta.self
let newNode = obj;
if (Array.isArray(obj)) {
newNode = obj.slice();
newNode.forEach((item, idx) => {
newNode[idx] = innerDeep(item);
});
}
if (isSet(obj)) {
const tmpArr = Array.from(obj);
tmpArr.forEach((item, idx) => {
tmpArr[idx] = innerDeep(item);
});
newNode = new Set(tmpArr);
}
if (isMap(obj)) {
newNode = new Map(obj);
newNode.forEach((value, key) => {
newNode.set(key, innerDeep(value));
});
}
if (isObject(obj)) {
newNode = {};
Object.keys(obj).forEach((key) => {
newNode[key] = innerDeep(obj[key]);
});
}
return newNode;
};
return innerDeep(obj);
}
export function makeCopy(val) {
if (Array.isArray(val)) {
return val.slice();
}
if (isObject(val)) {
return Object.assign({}, val);
}
if (isMap(val)) {
return new Map(val);
}
if (isSet(val)) {
return new Set(val);
}
return val;
}
/**
* 尝试生成copy
* @param val
* @returns
*/
export function tryMakeCopy(val, readOnly) {
if (readOnly) {
return val;
}
if (Array.isArray(val)) {
return val.slice();
}
let copy = val;
if (val && isObject(val)) {
copy = Object.assign({}, val);
}
if (isMap(val)) {
copy = new Map(val);
}
if (isSet(val)) {
copy = new Set(val);
}
return copy;
}
// 调用处已保证 meta 不为空
export function mayMakeCopy(ori, options) {
// LABEL: SEE IF IMMUT HAS MEM LEAK
if (options.immutBase) {
return ori;
}
const copy = tryMakeCopy(ori, options.readOnly);
return copy;
}