Як отримати розмір об’єкта JavaScript?


296

Я хочу знати розмір, який займає об’єкт JavaScript.

Виконайте таку функцію:

function Marks(){
  this.maxMarks = 100;
}

function Student(){
  this.firstName = "firstName";
  this.lastName = "lastName";
  this.marks = new Marks();
}

Тепер я інстанціюю student:

var stud = new Student();

так що я можу робити такі речі

stud.firstName = "new Firstname";

alert(stud.firstName);

stud.marks.maxMarks = 200;

тощо.

Тепер studоб’єкт буде займати деякий розмір в пам'яті. У ньому є деякі дані та більше об’єктів.

Як дізнатися, скільки пам’яті studзаймає об’єкт? Щось схоже на sizeof()JavaScript? Це було б справді дивовижно, якби я міг знайти це в одному виклику функції, як sizeof(stud).

Я шукав в Інтернеті місяцями - не міг його знайти (запитували на кількох форумах - відповідей не було).


41
Є (виникне) безліч причин, чому мені потрібно знайти розмір об'єкта в JavaScript. Я новачок у JavaScript, тому я не дотримуюся найкращих практик. Я все ще їх вчу. Я розробив розширення для firefox, яке, я впевнений, використовує більше пам'яті, ніж слід. Я працюю над деякими способами (сподіваюсь) зменшити використання пам'яті .. я говорю про тисячі примірників багатьох об'єктів на вкладку, тому пам'ять має значення! Річ у тому, що я хочу знати, чи дійсно мої зусилля щодо зменшення пам’яті допомагають зменшити пам’ять .. і на скільки.

1
Якщо ви створили розширення FF, я б радив дослідити на більш високому рівні мови, ніж JS - подивіться, який вплив має сам FF.
annakata

2
Мова вищого рівня, ніж JS? що б це було в цьому випадку?

24
Це не так важливий розмір. Це як ви цим користуєтеся. PS: Яка шпилька!
Томас Едінг

13
@SpencerRuport Номер одна з причин того, щоб знати розмір об'єкта, - це програми, здатні до використання в режимі офлайн html5, де у вас іноді обмежений обсяг пам’яті (5-10Mb можна швидко з'їсти для інтенсивного застосування даних).
Девід

Відповіді:


181

Я повторно ознайомив з кодом у своїй оригінальній відповіді . Я видалив рекурсію і видалив передбачуване існування накладних витрат.

function roughSizeOfObject( object ) {

    var objectList = [];
    var stack = [ object ];
    var bytes = 0;

    while ( stack.length ) {
        var value = stack.pop();

        if ( typeof value === 'boolean' ) {
            bytes += 4;
        }
        else if ( typeof value === 'string' ) {
            bytes += value.length * 2;
        }
        else if ( typeof value === 'number' ) {
            bytes += 8;
        }
        else if
        (
            typeof value === 'object'
            && objectList.indexOf( value ) === -1
        )
        {
            objectList.push( value );

            for( var i in value ) {
                stack.push( value[ i ] );
            }
        }
    }
    return bytes;
}

35
ви можете також придумати клавіші об'єкта
zupa

8
Кожен, хто приземлився тут, шукаючи найменший тип для цілей false / true, він, здається, не визначений / null.
zupa

3
"よんもじ".lengthу Javascript - 4, але ви впевнені, що це 8 байт, оскільки ваш код повертає його?
syockit

8
Так. Символи в JavaScript зберігаються відповідно до специфікації 3-го видання ECMA-262 - bclary.com/2004/11/07/#a-4.3.16
thomas-peter

4
Ця функція не рахує посилань, прихованих у закриттях. Наприклад var a={n:1}; var b={a:function(){return a}}; roughSizeOfObject(b)- тут bміститься посилання на a, але roughSizeOfObject()повертається 0.
Роман Помінов

116

Google Chrome Heap Profiler дозволяє вам перевірити використання об’єктної пам'яті.

Вам потрібно вміти знаходити об’єкт у сліді, який може бути складним. Якщо ви зафіксуєте об'єкт у глобальному вікні, його легко знайти в режимі лістингу "Containment".

На доданому скріншоті я створив об’єкт під назвою "testObj" у вікні. Потім я розміщуюсь у профіле (після запису) і він показує повний розмір об'єкта і все, що знаходиться в ньому, під "нерозмірним розміром".

Детальніше про поломки пам'яті .

Профілер Chrome

На наведеному вище скріншоті об'єкт показує збережений розмір 60. Я вважаю, що одиниця тут є байтами.


13
Ця відповідь вирішила мою проблему разом із: developers.google.com/chrome-developer-tools/docs/… . Короткий підказок: зробіть швидкий знімок із купи, виконайте завдання, яке підозрює, що протікає, зробіть новий швидкий знімок купи та виберіть comparisonподання внизу. Зрозуміло, які об’єкти були створені між двома знімками.
Джонріда

1
Це, мабуть, найчистіше рішення.
Лука Стіб

Порівняння, згадане @Johnride, тепер є спадне меню вгорі.
frandroid

Shallow sizeвидається 40 як для об'єктів, так { a:"55c2067aee27593c03b7acbe", b:"55c2067aee27593c03b7acbe", c:null, d:undefined }і для них { c:null, d:undefined }. Чи гаразд?
efkan

1
Ви також можете використовувати Google Chrome Heap Profiler і з вузла. Якщо у вас є вузол v8 або вище, запустіть його node --inspectта в Chrome введіть about:inspectу рядку URL-адреси та шукайте відкриття інспектора вузла. Створіть свій об'єкт у вузлі CLI, а потім зробіть знімок у купі.
Грегор

74

Я щойно написав це, щоб вирішити подібну проблему. Він не відповідає саме тому, що ви можете шукати, тобто не враховує, як інтерпретатор зберігає об'єкт.

Але, якщо ви використовуєте V8, це повинно дати вам цілком нормальне наближення, оскільки дивовижне прототипування та приховані класи вилизують більшу частину накладних витрат.

function roughSizeOfObject( object ) {

    var objectList = [];

    var recurse = function( value )
    {
        var bytes = 0;

        if ( typeof value === 'boolean' ) {
            bytes = 4;
        }
        else if ( typeof value === 'string' ) {
            bytes = value.length * 2;
        }
        else if ( typeof value === 'number' ) {
            bytes = 8;
        }
        else if
        (
            typeof value === 'object'
            && objectList.indexOf( value ) === -1
        )
        {
            objectList[ objectList.length ] = value;

            for( i in value ) {
                bytes+= 8; // an assumed existence overhead
                bytes+= recurse( value[i] )
            }
        }

        return bytes;
    }

    return recurse( object );
}

1
@Liangliang Zheng - чудова краща нескінченна петля, дякую. Сподіваюсь, ви не заперечуєте, якщо я трохи перенастрою його та оновлюю шахту після роботи (?)
thomas-peter

Я збираюся перевірити це сьогодні ввечері з node.js і отримаю кілька кращих коефіцієнтів.
thomas-peter

Рядок 'байти + = повтор (значення [i])', видає помилку в моєму FF 14.01: NS_ERROR_FAILURE: Компонент повернув код відмови: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMHTMLInputElement.selectionStart]. На одному з моїх об'єктів, якщо я спробую інший, він не спрацьовує, можливо, помилка браузера або код не працює для кожного об'єкта (той, який не працює, містить функції, той, який працює, не працює ' t)
TrySpace

1
Від одного Тома до іншого, це стало дуже корисним як приблизний показник того, де мені потрібно обрізати талію об'єкта. Тож ваш місіс дізнався про вашу справу з Javascript? Вона майстра з високого обслуговування.
Том У Хол

4
На це я повинен пильнувати PHP (gulp) - я давно її перестав любити, але вона платить рахунки. У будь-якому випадку, дякую Тому, відгуки, які подобаються, є набагато кращими за репутаційні бали.
thomas-peter

55

Іноді я використовую це для позначення дійсно великих об'єктів, які можуть надходити до клієнта з сервера. Він не відображає слід пам'яті. Він просто отримує приблизно те, що коштувало б надіслати або зберегти.

Також зауважте, що це повільно, лише розробник. Але для отримання відповіді на тему з одним рядком коду мені це було корисно.

roughObjSize = JSON.stringify(bigObject).length;

2
З моїх тестів, цей метод значно швидший, ніж випадок розміру об'єкта, оскільки він не має повільного виклику _.isObject () від lodash. Крім того, розміри, що повертаються, досить порівнянні для приблизних оцінок. Gist gist.github.com/owenallenaz/ff77fc98081708146495 .
Нуклеон


5
Не можна використовувати з круговими структурами VM1409:1 Uncaught TypeError: Converting circular structure to JSON:( все ще корисно, хоча
givanse

Це не двійковий розмір у байтах, а простий у використанні для отримання приблизного розміру
datdinhquoc

Це досить чудово, якщо 1) вам потрібна лише бальна оцінка 2) ви знаєте, що у вас немає кругових посилань 3) ви можете опускати великі значення і змішувати їх окремо. Все це було правдою в моєму випадку, тому працює чудово, у мене було лише одне велике рядок в одному місці, на якому я можу просто виміряти довжину.
OZZIE

43

Ось дещо компактніше рішення проблеми:

const typeSizes = {
  "undefined": () => 0,
  "boolean": () => 4,
  "number": () => 8,
  "string": item => 2 * item.length,
  "object": item => !item ? 0 : Object
    .keys(item)
    .reduce((total, key) => sizeOf(key) + sizeOf(item[key]) + total, 0)
};

const sizeOf = value => typeSizes[typeof value](value);

3
так це розмір у КБ? чи шматочки?
Вінсент Торп

2
@ vincent-thorpe Це в байтах.
Дан

2
Хороший сценарій, хоча потрібні модифікації для циклічних посилань.
Джим Педід

1
Я щойно перевіряв ваш алгоритм на величезному масиві даних у процесі вузла, він повідомляє 13 ГБ, але вузол споживає 22 ГБ, будь-яке уявлення про те, звідки походить різниця? Більше нічого немає в пам’яті.
Джосу Гоні

3
@ JosuGoñi, вони не підраховують, скільки саме об'єкт бере, а лише його значення. Всі об'єкти займають більше місця, ніж просто їхня вартість, інакше typeof ...б це не працювало.
Алексіс Вілке

42

Існує модуль NPM, щоб отримати розмір об'єктаof , ви можете встановити йогоnpm install object-sizeof

  var sizeof = require('object-sizeof');

  // 2B per character, 6 chars total => 12B
  console.log(sizeof({abc: 'def'}));

  // 8B for Number => 8B
  console.log(sizeof(12345));

  var param = { 
    'a': 1, 
    'b': 2, 
    'c': {
      'd': 4
    }
  };
  // 4 one two-bytes char strings and 3 eighth-bytes numbers => 32B
  console.log(sizeof(param));

sizeof (нова дата ()) === 0 і sizeof ({}) === 0. Це призначено?
Філіп Класен

1
@ PhilippClaßen Очевидно, що це так. Обидва об'єкти не мають властивостей.
Роберт

18

Це гакітний метод, але я спробував його двічі з різними цифрами, і, здається, він відповідає.

Що ви можете зробити, це спробувати виділити величезну кількість об'єктів, як-от один або два мільйони об'єктів, які ви хочете. Помістіть об’єкти в масив, щоб перешкоджати видачі сміттєзбірника (зверніть увагу, що це додасть невелику накладну пам’ять через масив, але я сподіваюся, що це не має значення, і, крім того, якщо ви будете турбуватися про те, що об’єкти знаходяться в пам'яті , ви їх десь зберігаєте). Додайте попередження до та після розподілу та в кожному попередженні перевіряйте, скільки пам'яті займає процес Firefox. Перш ніж відкрити сторінку з тестом, переконайтеся, що у вас є свіжий екземпляр Firefox. Відкрийте сторінку, зверніть увагу на використання пам'яті після появи попередження "до". Закрийте сповіщення, зачекайте, поки буде виділено пам'ять. Відняти нову пам’ять від старшої та розділити її на кількість виділень.

function Marks()
{
  this.maxMarks = 100;
}

function Student()
{
  this.firstName = "firstName";
  this.lastName = "lastName";
  this.marks = new Marks();
}

var manyObjects = new Array();
alert('before');
for (var i=0; i<2000000; i++)
    manyObjects[i] = new Student();
alert('after');

Я спробував це на своєму комп’ютері, і процес мав 48352K пам'яті, коли було показано попередження "до". Після виділення Firefox мав 440236K пам'яті. Для 2 мільйонів виділень, це приблизно 200 байт на кожен об'єкт.

Я спробував це ще раз з 1 мільйонами виділень, і результат був подібний: 196 байт на об'єкт (я вважаю, додаткові дані в 2mill використовувались для Array).

Отже, ось прискіпливий метод, який може вам допомогти. JavaScript не дає методу "sizeof" з причини: кожна реалізація JavaScript відрізняється. Наприклад, в Google Chrome на одній і тій же сторінці використовується близько 66 байт для кожного об’єкта (судячи з принаймні менеджера завдань).


Гей .. спасибі за техніку. У мене це було, як у плані В, якщо не було прямого способу вимірювання використання пам'яті.

4
Кожна реалізація C і C ++ також відрізняється. ;) Розмір типу даних в C або C ++ залежить від реалізації. Я не бачу причин, що JavaScript не може підтримувати такого оператора, хоча він не буде виконувати ту саму ціль або мати те саме значення, що і в C або C ++ (які є мовами нижчого рівня і вимірюють фактичний розмір фіксованого, тип даних розміру під час компіляції, на відміну від розміру змінного динамічного об’єкта JavaScript під час виконання).
бамбуки

12

Вибачте, що не зміг прокоментувати, тому я просто продовжую роботу з tomwrong. Ця розширена версія не буде рахувати об'єкт більше одного разу, таким чином, не існує нескінченного циклу. Плюс, я вважаю, що ключ об'єкта також повинен бути підрахований, приблизно.

function roughSizeOfObject( value, level ) {
    if(level == undefined) level = 0;
    var bytes = 0;

    if ( typeof value === 'boolean' ) {
        bytes = 4;
    }
    else if ( typeof value === 'string' ) {
        bytes = value.length * 2;
    }
    else if ( typeof value === 'number' ) {
        bytes = 8;
    }
    else if ( typeof value === 'object' ) {
        if(value['__visited__']) return 0;
        value['__visited__'] = 1;
        for( i in value ) {
            bytes += i.length * 2;
            bytes+= 8; // an assumed existence overhead
            bytes+= roughSizeOfObject( value[i], 1 )
        }
    }

    if(level == 0){
        clear__visited__(value);
    }
    return bytes;
}

function clear__visited__(value){
    if(typeof value == 'object'){
        delete value['__visited__'];
        for(var i in value){
            clear__visited__(value[i]);
        }
    }
}

roughSizeOfObject(a);

Я думаю, що це точніше, оскільки він рахує ключі, хоча він рахує клавішу "__visited__"
Сем Хаслер

Перевірка typeof value === 'object'недостатня, і у вас є винятки, якщо значення є null.
флорібон

Це вибухнуло швидко для мого об'єкта (який я досить впевнений, що він подолав 5 Мб), порівняно з будь-якою з дурних відповідей @ tomwrong. Це також було більш точним (як було сказано, 3 Мб або близько того), але все-таки занадто далеко від реальності. Будь-які підказки щодо того, на що він може не рахуватися?
Крегокс

Не працює для мене. Об'єкт levelмістить дані, але roughSizeOfObject(level)повертає нуль. (Звичайно, мій мінливий рівень не слід плутати з вашим аргументом. Я не думаю, що затінення змінної повинно викликати тут проблему, а також, коли я перейменую 'рівень' у вашому сценарії, я отримую такий же результат.) Скріншот : snipboard.io/G7E5yj.jpg
Люк

10

З тією ж проблемою. Я шукав у Google, і хочу поділитися з спільнотою stackoverflow цим рішенням.

Важливо :

Я використав функцію, якою поділився Ян Цін на github https://gist.github.com/zensh/4975495

function memorySizeOf(obj) {
    var 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':
                var objClass = Object.prototype.toString.call(obj).slice(8, -1);
                if(objClass === 'Object' || objClass === 'Array') {
                    for(var 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";
    };

    return formatByteSize(sizeOf(obj));
};


var sizeOfStudentObject = memorySizeOf({Student: {firstName: 'firstName', lastName: 'lastName', marks: 10}});
console.log(sizeOfStudentObject);

Що ви думаєте про це?


3
При цьому відсутні функції. Якщо я додаю функцію, об’єкт не відображатиметься як більший
Дон Роммі

Не рахує ключі
ebg11

7

я хочу знати, чи дійсно мої зусилля щодо зменшення пам’яті допомагають зменшити пам’ять

Слідкуючи за цим коментарем, ось що вам слід зробити: Спробуйте створити проблему з пам’яттю - Напишіть код, який створює всі ці об’єкти, і грайдально збільшуйте верхню межу, поки ви не зіткнетеся з проблемою (Збій браузера, заморозка браузера або вихід із-за- помилка пам'яті). В ідеалі слід повторити цей експеримент із різними браузерами та різною операційною системою.

Зараз є два варіанти: варіант 1 - Вам не вдалося створити проблему з пам'яттю. Отже, ви нічого не турбуєтесь. У вас немає проблеми з пам'яттю, і ваша програма прекрасна.

варіант 2 - у вас виникла проблема з пам'яттю. Тепер запитайте себе, чи розумна межа, з якою виникла проблема (іншими словами: чи ймовірно, що ця кількість об'єктів буде створена при нормальному використанні вашого коду). Якщо відповідь «Ні», то ви все добре. Інакше тепер ви знаєте, скільки об’єктів може створити ваш код. Переробіть алгоритм таким чином, щоб він не порушив цю межу.


З точки зору стояння пам’яті, моє розширення додає ряд об’єктів для кожної сторінки / вкладки, відкритої у Firefox. "Число" пропорційне розміру сторінки. Якщо припустити, що "владні" користувачі відкриті десь між 15 - 20 вкладками, і якщо на веб-сторінці багато вмісту, браузер через деякий час стає повільним і розчаровуючи невідчутливим. Це трапляється навіть без явної спроби підкреслити додаток. У мене є плани переписати код, який, на мою думку, зменшить велику кількість об'єктів. Я просто хотів бути впевненим, що ні. об’єктів зменшено склало щось настільки, що воно того варте

@Senthil: але розмір об'єкта не має жодного значення, якщо ви не знаєте об'єм доступної пам'яті. Оскільки об'єм пам'яті, ймовірно, залишиться загадкою, говорити в термінах #objects так само корисно, як і говорити в терміні # байтів
Itay Maman


5

Ця бібліотека Javascript sizeof.jsробить те саме. Включіть це так

<script type="text/javascript" src="sizeof.js"></script>

Функція sizeof приймає об’єкт як параметр і повертає його приблизний розмір у байтах. Наприклад:

// define an object
var object =
    {
      'boolean' : true,
      'number'  : 1,
      'string'  : 'a',
      'array'   : [1, 2, 3]
    };

// determine the size of the object
var size = sizeof(object);

Функція sizeof може обробляти об'єкти, які містять кілька посилань на інші об'єкти та рекурсивні посилання.

Спочатку опубліковано тут .


Це повільніше, і в моєму випадку використання виявляється "менш точним", ніж @liangliang.
Крегокс


2

Дякую всім, хто працював над цим кодом!

Я просто хотів додати, що я шукав саме те саме, але в моєму випадку це управління кешем оброблюваних об'єктів, щоб уникнути необхідності повторного розбору та обробки об’єктів з викликів ajax, які можуть бути або не можуть бути кешовані за допомогою браузера. Це особливо корисно для об'єктів, для яких потрібна велика обробка, як правило, все, що не у форматі JSON, але це може коштувати дуже дорого, щоб зберегти кеш цих речей у великому проекті або додатку / розширенні, яке довго працюватиме час.

У всякому разі, я використовую це для чогось такого типу:

var myCache = {
    cache: {},
    order: [],
    size: 0,
    maxSize: 2 * 1024 * 1024, // 2mb

    add: function(key, object) {
        // Otherwise add new object
        var size = this.getObjectSize(object);
        if (size > this.maxSize) return; // Can't store this object

        var total = this.size + size;

        // Check for existing entry, as replacing it will free up space
        if (typeof(this.cache[key]) !== 'undefined') {
            for (var i = 0; i < this.order.length; ++i) {
                var entry = this.order[i];
                if (entry.key === key) {
                    total -= entry.size;
                    this.order.splice(i, 1);
                    break;
                }
            }
        }

        while (total > this.maxSize) {
            var entry = this.order.shift();
            delete this.cache[entry.key];
            total -= entry.size;
        }

        this.cache[key] = object;
        this.order.push({ size: size, key: key });
        this.size = total;
    },

    get: function(key) {
        var value = this.cache[key];
        if (typeof(value) !== 'undefined') { // Return this key for longer
            for (var i = 0; i < this.order.length; ++i) {
                var entry = this.order[i];
                if (entry.key === key) {
                    this.order.splice(i, 1);
                    this.order.push(entry);
                    break;
                }
            }
        }
        return value;
    },

    getObjectSize: function(object) {
        // Code from above estimating functions
    },
};

Це спрощений приклад і може мати деякі помилки, але він дає ідею, оскільки ви можете використовувати його для тримання на статичних об'єктах (вміст не зміниться) з певною мірою інтелекту. Це може суттєво зменшити будь-які дорогі вимоги до обробки, які об'єкт повинен був виготовити в першу чергу.


1
function sizeOf(parent_data, size)
{
    for (var prop in parent_data)
    {
        let value = parent_data[prop];

        if (typeof value === 'boolean')
        {
            size += 4;
        }
        else if (typeof value === 'string')
        {
            size += value.length * 2;
        }
        else if (typeof value === 'number')
        {
             size += 8;
        }
        else
        {      
            let oldSize = size;
            size += sizeOf(value, oldSize) - oldSize;
        }
    }

    return size;
}


function roughSizeOfObject(object)
{   
    let size = 0;
    for each (let prop in object)
    {    
        size += sizeOf(prop, 0);
    } // for..
    return size;
}

1

Я використовую вкладку Тимчасова шкала інструментів для розробників , інстанціюю все більшу кількість об'єктів і отримую такі хороші оцінки. Ви можете використовувати HTML, подібний до цього, як котлован, і модифікувати його, щоб краще моделювати характеристики ваших об'єктів (кількість та типи властивостей тощо). Ви можете натиснути піктограму біт сміття в нижній частині вкладки інструментів розробника до та після запуску.

<html>
<script>
var size = 1000*100
window.onload = function() {
  document.getElementById("quantifier").value = size
}

function scaffold()
{
  console.log("processing Scaffold...");
  a = new Array
}

function start()
{
  size = document.getElementById("quantifier").value
  console.log("Starting... quantifier is " + size);
  console.log("starting test")
  for (i=0; i<size; i++){
    a[i]={"some" : "thing"}
  }
  console.log("done...")
}

function tearDown()
{
  console.log("processing teardown");
  a.length=0
}

</script>
<body>
    <span style="color:green;">Quantifier:</span>
    <input id="quantifier" style="color:green;" type="text"></input>
    <button onclick="scaffold()">Scaffold</button>
    <button onclick="start()">Start</button>
    <button onclick="tearDown()">Clean</button>
    <br/>
</body>
</html>

Ініціалізація 2 мільйонів об'єктів лише однієї властивості (як у цьому коді вище) призводить до приблизного обчислення 50 байтів на об'єкт у моєму Chromium зараз. Зміна коду для створення випадкового рядка на об'єкт додає приблизно 30 байт на об'єкт тощо. Сподіваюся, це допоможе.


1

Якщо вам потрібно систематично перевірити наявність aprox. розмір об'єктів, ви також можете перевірити цю бібліотеку http://code.stephenmorley.org/javascript/finding-the-memory-usage-of-objects/ яку я зміг використовувати для розміру об'єктів.

В іншому випадку я пропоную використовувати Chrome / Firefox Heap Profiler.


-3

Я вважаю, ви забули включити "масив".

  typeOf : function(value) {
        var s = typeof value;
        if (s === 'object')
        {
            if (value)
            {
                if (typeof value.length === 'number' && !(value.propertyIsEnumerable('length')) && typeof value.splice === 'function')
                {
                    s = 'array';
                }
            }
            else
            {
                s = 'null';
            }
        }
        return s;
    },

   estimateSizeOfObject: function(value, level)
    {
        if(undefined === level)
            level = 0;

        var bytes = 0;

        if ('boolean' === typeOf(value))
            bytes = 4;
        else if ('string' === typeOf(value))
            bytes = value.length * 2;
        else if ('number' === typeOf(value))
            bytes = 8;
        else if ('object' === typeOf(value) || 'array' === typeOf(value))
        {
            for(var i in value)
            {
                bytes += i.length * 2;
                bytes+= 8; // an assumed existence overhead
                bytes+= estimateSizeOfObject(value[i], 1)
            }
        }
        return bytes;
    },

   formatByteSize : function(bytes)
    {
        if (bytes < 1024)
            return bytes + " bytes";
        else
        {
            var floatNum = bytes/1024;
            return floatNum.toFixed(2) + " kb";
        }
    },

1
У JS масив є об'єктом. У реалізації може бути певна оптимізація, але концептуальні масиви та об'єкти однакові.
Кріс Уокер

-8

Я знаю це абсолютно не правильний спосіб зробити це, але це мені кілька разів допомагало в минулому отримати розмір файлу приблизного об'єкта:

Напишіть свій об’єкт / відповідь на консоль або нову вкладку, скопіюйте результати в новий файл блокнота, збережіть його та перевірте розмір файлу. Сам файл блокнота - це лише кілька байт, тому ви отримаєте досить точний розмір об'єктного файлу.


4
Це абсолютно неправильно. Наприклад, розглянемо число 1/3 = 0,3333333333333333. Це буде 18 байт, використовуючи ваш підхід.
korCZis

2
Я сказав, що це приблизне . Іноді вам не байдуже, чи це 1 Мб або 1 0001 МБ, ви просто хочете дізнатися оцінку, тоді цей метод ідеально чудовий.
Джефрі Росендаал

Примхливе рішення X]
Лапіс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.