function cloneInstance( val ) {
	var cache;
	var names;
	var name;
	var refs;
	var desc;
	var tmp;
	var ref;
	var i;

	cache = [];
	refs = [];

	ref = Object.create( getPrototypeOf( val ) );
	cache.push( val );
	refs.push( ref );

	names = propertyNames( val );
	for ( i = 0; i < names.length; i++ ) {
		name = names[ i ];
		desc = propertyDescriptor( val, name );
		if ( hasOwnProp( desc, 'value' ) ) {
			tmp = ( isArray( val[name] ) ) ? [] : {};
			desc.value = deepCopy( val[name], tmp, cache, refs, -1 );
		}
		defineProperty( ref, name, desc );
	}
	if ( !Object.isExtensible( val ) ) {
		Object.preventExtensions( ref );
	}
	if ( Object.isSealed( val ) ) {
		Object.seal( ref );
	}
	if ( Object.isFrozen( val ) ) {
		Object.freeze( ref );
	}
	return ref;
}
Clones a class instance.

## Notes

-   This should **only** be used for simple cases. Any instances with privileged access to variables (e.g., within closures) cannot be cloned. This approach should be considered **fragile**.
-   The function is greedy, disregarding the notion of a `level`. Instead, the function deep copies all properties, as we assume the concept of `level` applies only to the class instance reference but not to its internal state. This prevents, in theory, two instances from sharing state.

@private
@param {Object} val - class instance
@returns {Object} new instance