2017年1月19日 星期四

(js)readDataOnly

/**
 * 只做表層複製
 * 
 * 只能確定{}[]的表層資料不能改變,不能刪除
 */
function readDataOnly(source) {

    var toString = Object.prototype.toString;
    var clone;
    var type = _getType(source);

    if (/array/gi.test(type) || _isPlainObject(source)) {
        // source is [], {}
        clone = _copyProperty(source);
    } else if (/map/gi.test(type)) {
        // source is Map
        clone = _copyMap(source);
    } else {
        clone = source;
    }
    return clone;
};
/**
 * copy([], {})
 */
function _copyProperty(source) {
    debugger;

    if (!isObject(source)) {
        return source;
    } else {
        var copy;
        var prototype = Object.getPrototypeOf(source);
        /* ---------------------------------- */
        if (typeof prototype != 'undefined') {
            copy = Object.create(prototype);
        } else {
            copy = Object.create(null);
        }
        /* ---------------------------------- */
        copyProperty(copy, source);

        return copy;
    }
    /* =========================================== */
    /**
     * 是否是Object
     */
    function isObject(value) {
        debugger;

        var result = (value === Object(value));
        return result;
    };
    /* =========================================== */

    function copyProperty(copy, source) {
        var propertys = Object.getOwnPropertyNames(source);

        console.dir(propertys);

        propertys.forEach(function(property) {
            var desc = Object.getOwnPropertyDescriptor(source, property);

            // 禁止表層資料被修改新增刪除
            desc.writable = false;
            desc.configurable = false;

            Object.defineProperty(copy, property, desc);
        });
    };
};
/**
 * copy map
 */
function _copyMap(source) {
    var cloneMap = new Map();

    source.forEach(function(v, k) {
        cloneMap.set(k, v);
    });

    return cloneMap;
};
/* ====================================================================== */
/**
 * 確定型別
 */
function _getType(obj) {
    var type = toString.call(obj) || '';
    type = type.replace(/(^\s?\[object\s?)|(\]\s?$)/gi, '').toLowerCase();
    return type;
};
/* ====================================================================== */
/**
 * 是否是{}
 */
function _isPlainObject(obj) {
    if (!obj || _getType(obj) !== "object") {
        return false;
    }

    var constructorName = '';
    try {
        constructorName = obj.constructor.toString();
    } catch (error) {}

    // 'Object() {[native code]}'
    if (!/function\s*Object\(\s*\)\s*\{\s*\[native\s*code\]\s*\}\s*$/gi.test(constructorName)) {
        return false;
    }
    return true;
};