The source code

    /**
     * @ignore
     *   lang
     * @author  yiminghe@gmail.com, lifesinger@gmail.com
     *
     */
    (function (S, undefined) {

        var TRUE = true,
            FALSE = false,
            CLONE_MARKER = '__~ks_cloned',
            COMPARE_MARKER = '__~ks_compared';

        S.mix(S, {
                /**
                 * Checks to see whether two object are equals.
                 * @param a 比较目标1
                 * @param b 比较目标2
                 * @return {Boolean} a.equals(b)
                 * @member KISSY
                 */
                equals: function (a, b, /*internal use*/mismatchKeys, /*internal use*/mismatchValues) {
                    // inspired by jasmine
                    mismatchKeys = mismatchKeys || [];
                    mismatchValues = mismatchValues || [];

                    if (a === b) {
                        return TRUE;
                    }
                    if (a === undefined || a === null || b === undefined || b === null) {
                        // need type coercion
                        return a == null && b == null;
                    }
                    if (a instanceof Date && b instanceof Date) {
                        return a.getTime() == b.getTime();
                    }
                    if (typeof a == 'string' && typeof b == 'string') {
                        return (a == b);
                    }
                    if (S.isNumber(a) && S.isNumber(b)) {
                        return (a == b);
                    }
                    if (typeof a === 'object' && typeof b === 'object') {
                        return compareObjects(a, b, mismatchKeys, mismatchValues);
                    }
                    // Straight check
                    return (a === b);
                },

                /**
                 * Creates a deep copy of a plain object or array. Others are returned untouched.
                 * @param input
                 * @member KISSY
                 * @param {Function} [filter] filter function
                 * @return {Object} the new cloned object
                 * refer: http://www.w3.org/TR/html5/common-dom-interfaces.html#safe-passing-of-structured-data
                 */
                clone: function (input, filter) {
                    // 稍微改改就和规范一样了 :)
                    // Let memory be an association list of pairs of objects,
                    // initially empty. This is used to handle duplicate references.
                    // In each pair of objects, one is called the source object
                    // and the other the destination object.
                    var memory = {},
                        ret = cloneInternal(input, filter, memory);
                    S.each(memory, function (v) {
                        // 清理在源对象上做的标记
                        v = v.input;
                        if (v[CLONE_MARKER]) {
                            try {
                                delete v[CLONE_MARKER];
                            } catch (e) {
                                // S.log('delete CLONE_MARKER error : ');
                                v[CLONE_MARKER] = undefined;
                            }
                        }
                    });
                    memory = null;
                    return ret;
                },

                /**
                 * Gets current date in milliseconds.
                 * @method
                 * refer:  https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/now
                 * http://j-query.blogspot.com/2011/02/timing-ecmascript-5-datenow-function.html
                 * http://kangax.github.com/es5-compat-table/
                 * @member KISSY
                 * @return {Number} current time
                 */
                now: Date.now || function () {
                    return +new Date();
                }
            });

        function cloneInternal(input, f, memory) {
            var destination = input,
                isArray,
                isPlainObject,
                k,
                stamp;
            if (!input) {
                return destination;
            }

            // If input is the source object of a pair of objects in memory,
            // then return the destination object in that pair of objects .
            // and abort these steps.
            if (input[CLONE_MARKER]) {
                // 对应的克隆后对象
                return memory[input[CLONE_MARKER]].destination;
            } else if (typeof input === 'object') {
                // 引用类型要先记录
                var constructor = input.constructor;
                if (S.inArray(constructor, [Boolean, String, Number, Date, RegExp])) {
                    destination = new constructor(input.valueOf());
                }
                // ImageData , File, Blob , FileList .. etc
                else if (isArray = S.isArray(input)) {
                    destination = f ? S.filter(input, f) : input.concat();
                } else if (isPlainObject = S.isPlainObject(input)) {
                    destination = {};
                }
                // Add a mapping from input (the source object)
                // to output (the destination object) to memory.
                // 做标记
                input[CLONE_MARKER] = (stamp = S.guid());
                // 存储源对象以及克隆后的对象
                memory[stamp] = {destination: destination, input: input};
            }
            // If input is an Array object or an Object object,
            // then, for each enumerable property in input,
            // add a new property to output having the same name,
            // and having a value created from invoking the internal structured cloning algorithm recursively
            // with the value of the property as the 'input' argument and memory as the 'memory' argument.
            // The order of the properties in the input and output objects must be the same.

            // clone it
            if (isArray) {
                for (var i = 0; i < destination.length; i++) {
                    destination[i] = cloneInternal(destination[i], f, memory);
                }
            } else if (isPlainObject) {
                for (k in input) {

                    if (k !== CLONE_MARKER &&
                        (!f || (f.call(input, input[k], k, input) !== FALSE))) {
                        destination[k] = cloneInternal(input[k], f, memory);
                    }

                }
            }

            return destination;
        }

        function compareObjects(a, b, mismatchKeys, mismatchValues) {
            // 两个比较过了，无需再比较，防止循环比较
            if (a[COMPARE_MARKER] === b && b[COMPARE_MARKER] === a) {
                return TRUE;
            }
            a[COMPARE_MARKER] = b;
            b[COMPARE_MARKER] = a;
            var hasKey = function (obj, keyName) {
                return (obj !== null && obj !== undefined) && obj[keyName] !== undefined;
            };
            for (var property in b) {

                if (!hasKey(a, property) && hasKey(b, property)) {
                    mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
                }

            }
            for (property in a) {

                if (!hasKey(b, property) && hasKey(a, property)) {
                    mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
                }

            }
            for (property in b) {

                if (property == COMPARE_MARKER) {
                    continue;
                }
                if (!S.equals(a[property], b[property], mismatchKeys, mismatchValues)) {
                    mismatchValues.push("'" + property + "' was '" + (b[property] ? (b[property].toString()) : b[property])
                        + "' in expected, but was '" +
                        (a[property] ? (a[property].toString()) : a[property]) + "' in actual.");
                }

            }
            if (S.isArray(a) && S.isArray(b) && a.length != b.length) {
                mismatchValues.push('arrays were not the same length');
            }
            delete a[COMPARE_MARKER];
            delete b[COMPARE_MARKER];
            return (mismatchKeys.length === 0 && mismatchValues.length === 0);
        }

    })(KISSY);