getObjSize.mjs

/**
 * 計算物件記憶體大小
 *
 * Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/getObjSize.test.mjs Github}
 * @memberOf wsemi
 * @param {*} obj 傳入欲計算大小的任意數據
 * @returns {Object} 回傳記憶體大小物件, int屬性為記憶體所使用的bytes整數, str屬性為自動處理單位後的字串
 * @example
 *
 * console.log(getObjSize('abc123'))
 * // => 12
 *
 * console.log(getObjSize({ a: 123, b: 'xyz', c: '45op', d: null }))
 * // => 22
 *
 */
function getObjSize(obj) {

    let bytes = 0

    function sizeOf(obj) {
        if (obj !== null && obj !== undefined) {
            switch (typeof obj) {
            case 'number':
                bytes += 8
                break
            case 'string':
                bytes += obj.length * 2
                break
            case 'boolean':
                bytes += 4
                break
            case 'object':
                let objClass = Object.prototype.toString.call(obj).slice(8, -1)
                if (objClass === 'Object' || objClass === 'Array') {
                    for (let key in obj) {
                        if (!obj.hasOwnProperty(key)) continue
                        sizeOf(obj[key])
                    }
                }
                else {
                    bytes += obj.toString().length * 2
                }
                break
            }
        }
        return bytes
    }

    function formatByteSize(bytes) {
        if (bytes < 1024) return bytes + ' bytes'
        else if (bytes < 1048576) return (bytes / 1024).toFixed(3) + ' KiB'
        else if (bytes < 1073741824) return (bytes / 1048576).toFixed(3) + ' MiB'
        else return (bytes / 1073741824).toFixed(3) + ' GiB'
    }

    let isize = sizeOf(obj)
    let csize = formatByteSize(isize)

    return {
        int: isize,
        str: csize
    }
}


export default getObjSize