function cloneStructure(keys, getter, setter, traversedValues) {
  for (let key of keys) {
    let value = getter(key)
    let keyClone
    
    if (key instanceof Object) {
      if (traversedValues.has(key)) {
        keyClone = traversedValues.get(key)
      } else {
        keyClone = cloneValue(key, traversedValues)
        traversedValues.set(key, keyClone)
      }
    } else {
      keyClone = key
    }
    
    if (value instanceof Object) {
      if (traversedValues.has(value)) {
        setter(keyClone, traversedValues.get(value))
      } else {
        let clonedValue = cloneValue(value, traversedValues)
        traversedValues.set(value, clonedValue)
        setter(keyClone, clonedValue)
      }
    } else {
      setter(keyClone, value)
    }
  }
}
/**
 * Clones the structure having the specified property keys, using the provided
 * getters and setters. The function clones the keys and values before setting
 * them using the setters.
 * 
 * The cloned structure may contain circular references, the function keeps
 * track of those using the {@code traversedValues} map.
 * 
 * @param {(*[]|{[Symbol.iterator]: function(): {next: function(): *}})} keys
 *        The keys or iterator or iterable object generating the keys to
 *        properties to clone.
 * @param {function(*): *} getter A callback that returns the value of the
 *        source structure for the provided key.
 * @param {function(*, *)} setter A callback that sets the provided value (2nd
 *        argument) to the property identified by the specified key (1st
 *        argument) in the structure clone.
 * @param {Map<Object, Object>} traversedValues A map of traversed
 *        non-primitive keys and values. The keys are the keys and values
 *        traversed in the source structure or structures referencing this
 *        structure, the values are the clones of the keys and values.
 */
Clones the structure having the specified property keys, using the provided
getters and setters. The function clones the keys and values before setting
them using the setters.

The cloned structure may contain circular references, the function keeps
track of those using the  traversedValues map.

@param {(*[]|{[Symbol.iterator]: function(): {next: function(): *}})} keys
The keys or iterator or iterable object generating the keys to
properties to clone.
@param {function(*): *} getter A callback that returns the value of the
source structure for the provided key.
@param {function(*, *)} setter A callback that sets the provided value (2nd
argument) to the property identified by the specified key (1st
argument) in the structure clone.
@param {Map} traversedValues A map of traversed
non-primitive keys and values. The keys are the keys and values
traversed in the source structure or structures referencing this
structure, the values are the clones of the keys and values.
Clones the structure having the specified property keys using the provided getters and setters . The function clones the keys and values before setting them using the setters . The cloned structure may contain circular references the function keeps track of those using the traversedValues map . @param { ( * [] | { [ Symbol . iterator ] : function () : { next : function () : * }} ) } keys The keys or iterator or iterable object generating the keys to properties to clone . @param { function ( * ) : * } getter A callback that returns the value of the source structure for the provided key . @param { function ( * * ) } setter A callback that sets the provided value ( 2nd argument ) to the property identified by the specified key ( 1st argument ) in the structure clone . @param { Map } traversedValues A map of traversed non - primitive keys and values . The keys are the keys and values traversed in the source structure or structures referencing this structure the values are the clones of the keys and values .
function cloneStructure(keys, getter, setter, traversedValues) {
  for (let key of keys) {
    let value = getter(key)
    let keyClone
    if (key instanceof Object) {
      if (traversedValues.has(key)) {
        keyClone = traversedValues.get(key)
      } else {
        keyClone = cloneValue(key, traversedValues)
        traversedValues.set(key, keyClone)
      }
    } else {
      keyClone = key
    }
    if (value instanceof Object) {
      if (traversedValues.has(value)) {
        setter(keyClone, traversedValues.get(value))
      } else {
        let clonedValue = cloneValue(value, traversedValues)
        traversedValues.set(value, clonedValue)
        setter(keyClone, clonedValue)
      }
    } else {
      setter(keyClone, value)
    }
  }
}
function cloneStructure ( keys , getter , setter , traversedValues ) { for ( let key of keys ) { let value = getter ( key ) let keyClone if ( key instanceof Object ) { if ( traversedValues . has ( key ) ) { keyClone = traversedValues . get ( key ) } else { keyClone = cloneValue ( key , traversedValues ) traversedValues . set ( key , keyClone ) } } else { keyClone = key } if ( value instanceof Object ) { if ( traversedValues . has ( value ) ) { setter ( keyClone , traversedValues . get ( value ) ) } else { let clonedValue = cloneValue ( value , traversedValues ) traversedValues . set ( value , clonedValue ) setter ( keyClone , clonedValue ) } } else { setter ( keyClone , value ) } } }
Clones the structure having the specified property keys, using the provided
 getters and setters.
Clones the structure having the specified property keys using the provided getters and setters .