You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.0 KiB
84 lines
2.0 KiB
'use strict'; |
|
|
|
Object.defineProperty(exports, '__esModule', { |
|
value: true |
|
}); |
|
exports.default = deepCyclicCopy; |
|
|
|
/** |
|
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. |
|
* |
|
* This source code is licensed under the MIT license found in the |
|
* LICENSE file in the root directory of this source tree. |
|
*/ |
|
const EMPTY = new Set(); |
|
|
|
function deepCyclicCopy( |
|
value, |
|
options = { |
|
blacklist: EMPTY, |
|
keepPrototype: false |
|
}, |
|
cycles = new WeakMap() |
|
) { |
|
if (typeof value !== 'object' || value === null) { |
|
return value; |
|
} else if (cycles.has(value)) { |
|
return cycles.get(value); |
|
} else if (Array.isArray(value)) { |
|
return deepCyclicCopyArray(value, options, cycles); |
|
} else { |
|
return deepCyclicCopyObject(value, options, cycles); |
|
} |
|
} |
|
|
|
function deepCyclicCopyObject(object, options, cycles) { |
|
const newObject = options.keepPrototype |
|
? Object.create(Object.getPrototypeOf(object)) |
|
: {}; |
|
const descriptors = Object.getOwnPropertyDescriptors(object); |
|
cycles.set(object, newObject); |
|
Object.keys(descriptors).forEach(key => { |
|
if (options.blacklist && options.blacklist.has(key)) { |
|
delete descriptors[key]; |
|
return; |
|
} |
|
|
|
const descriptor = descriptors[key]; |
|
|
|
if (typeof descriptor.value !== 'undefined') { |
|
descriptor.value = deepCyclicCopy( |
|
descriptor.value, |
|
{ |
|
blacklist: EMPTY, |
|
keepPrototype: options.keepPrototype |
|
}, |
|
cycles |
|
); |
|
} |
|
|
|
descriptor.configurable = true; |
|
}); |
|
return Object.defineProperties(newObject, descriptors); |
|
} |
|
|
|
function deepCyclicCopyArray(array, options, cycles) { |
|
const newArray = options.keepPrototype |
|
? new (Object.getPrototypeOf(array).constructor)(array.length) |
|
: []; |
|
const length = array.length; |
|
cycles.set(array, newArray); |
|
|
|
for (let i = 0; i < length; i++) { |
|
newArray[i] = deepCyclicCopy( |
|
array[i], |
|
{ |
|
blacklist: EMPTY, |
|
keepPrototype: options.keepPrototype |
|
}, |
|
cycles |
|
); |
|
} |
|
|
|
return newArray; |
|
}
|
|
|