Питання Довжина об'єкта JavaScript


Якщо у мене є об'єкт JavaScript, скажіть

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

Чи є вбудований або прийнятий найкращий спосіб отримати довжину цього об'єкта?


1827
2017-08-07 19:42


походження


Об'єктні літерали в javascript є типовими асоціативними масивами, наприклад object.propertyName.propertyValue - це те саме, що і об'єкт [propertyName] [propertyValue] - neitony
Додано один вкладиш в Underscore.js, який робить це: stackoverflow.com/a/11346637/11236 - ripper234
Одного разу відповідь лінії полягає у використанні Object.keys (myArray) .length, як сказав @aeosynth. - Ranadheer Reddy
добре, а як Object.keys(obj).length - Muhammad Umer
Чому дійсна дійсна об'єкт? Він повертає мені правильний результат. - Adrian M


Відповіді:


Найбільш надійна відповідь (тобто, яка фіксує наміри того, що ви намагаєтесь виконати, принаймні виявлення помилок):

Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

// Get the size of an object
var size = Object.size(myArray);

У вас є така згода в JavaScript не додавати речі до Object.prototype, оскільки він може руйнувати переліки в різних бібліотеках. Додавання методів до об'єкта, як правило, безпечно.


Ось оновлення з 2016 року і широке розгортання ES5 і за його межами.  Для IE9 + та всіх інших сучасних браузерів з підтримкою ES5 + ви можете використовувати Object.keys() тому вищезгаданий код просто стає таким:

var size = Object.keys(myObj).length;

З цього моменту не потрібно змінювати будь-який існуючий прототип Object.keys() в даний час вбудований.

Редагувати: Об'єкти можуть мати символічні властивості, які не можуть бути повернуті за допомогою методу Object.key. Отже, відповідь буде неповною, не згадуючи їх.

Тип мови був доданий до мови для створення унікальних ідентифікаторів для властивостей об'єкта. Основною перевагою типу Symbol є запобігання перезапису.

Object.keys або Object.getOwnPropertyNames не працює для символічних властивостей. Щоб їх повернути, потрібно використовувати Object.getOwnPropertySymbols.

var person = {
  [Symbol('name')]: 'John Doe',
  [Symbol('age')]: 33,
  "occupation": "Programmer"
};

const propOwn = Object.getOwnPropertyNames(person);
console.log(propOwn.length); // 1

let propSymb = Object.getOwnPropertySymbols(person);
console.log(propSymb.length); // 2

2022
2017-08-09 08:31



@Tres - ваш код може бути зламаний, якщо хтось прийде та перевищить властивість "size", не знаючи, що ви вже заявили його вже десь у коді, тому завжди варто перевірити, чи він вже визначений - vsync
@ vsync Ви дуже правильні. Треба завжди виконувати необхідні перевірки здорового глузду :) - Tres
Чому кожен ігнорує це: Object.keys(obj).length - Muhammad Umer
@ MuhammadUmer Можливо, тому що цей метод навіть не існував, коли ця відповідь була написана. Навіть сьогодні, використовуючи його, можливо, буде потрібно поліфляж для старих браузерів. - Chris Hayes
@stonyau IE8, IE9, IE10 - це мертві веб-переглядачі, які не отримують підтримку від Microsoft. Користувач IE8, IE9, IE10 отримує повідомлення від корпорації Майкрософт про те, що вони використовують старий, непідтримуваний браузер, і слід очікувати, що для них не буде працювати. support.microsoft.com/en-us/kb/3123303 - Lukas


Якщо ви знаєте, що вам не потрібно турбуватися hasOwnProperty чеки, ви можете зробити це дуже просто:

Object.keys(myArray).length

1413
2018-04-03 01:44



чому ні? З того, що я знаю, це стандартне: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/... - vsync
Це не універсально реалізовано метод, але ви можете перевірити, який браузер підтримує його цей стіл. - aeosynth
Немає підтримки IE8 = не підуть. - ripper234
час переходу на firefox = на жаль, перемикання не означає, що користувачі вашого веб-сайту ... - mdup
@ ripper234 немає підтримки IE = час до заповнення - John Dvorak


Оновлено: Якщо ви використовуєте Underscore.js (рекомендовано, це легкий!), то ви можете просто зробити

_.size({one : 1, two : 2, three : 3});
=> 3

Якщо ні, і ви не хочете спотворювати властивості Object з будь-якої причини і вже використовуєте jQuery, плагін однаково доступний:

$.assocArraySize = function(obj) {
    // http://stackoverflow.com/a/6700/11236
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

252
2017-07-05 14:39



_.size() був ідеальним рішенням для мого Метеор проект, який підтримує underscore.js. - tokyovariable
Я використовую підкреслення, і цей пост просто нагадав мені, що я недостатньо використовую його в цьому проекті. Якщо ви обробляєте об'єкти, вам слід мати доступ до underscore.js. - jbolanos
Підкреслення> (все - ['lo-dash']) - Rayjax
Також отримав лолах.js  логода - hipkiss
@Babydead, щоб відрізнити реальні властивості об'єкта від успадкованих. developer.mozilla.org/en/docs/Web/JavaScript/Reference/... - ripper234


Використовуйте щось так просто:

Object.keys(obj).length

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


153
2017-10-27 03:46



Як це відрізняється від відповіді aeosynth? - DanMan
Ви бачили кількість відповідей на це питання? Коли я написав це, я не бачив (кілька) дублікатів. Джеймс Коглан відповідав таким чином за 3 роки до еосінхту, так що ви не читали всіх відповідей .... або ви б це бачили. - Michael
@ Майкл ні, він цього не зробив. Це було редагування іншого користувача з 02.02.2016. огляд - old_mountain


Ось найчастіше крос-браузерне рішення.

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

if (!Object.keys) {
    Object.keys = function (obj) {
        var arr = [],
            key;
        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                arr.push(key);
            }
        }
        return arr;
    };
}

Object.keys(obj).length;

43
2017-09-01 16:12



Object.keys() повертає масив, що містить імена лише тих перелітних властивостей. Якщо ви хочете мати масив з ВСІМИ властивостями, ви повинні використовувати Object.getOwnPropertyNames() замість цього. Побачити developer.mozilla.org/en/docs/Web/JavaScript/Reference/... - John Slegers


Я не експерт JavaScript, але, схоже, вам доведеться цикл по елементам і підрахувати їх, оскільки метод Object не має довжини.

var element_count = 0;
for (e in myArray) {  if (myArray.hasOwnProperty(e)) element_count++; }

@palmsey: У справедливості до OP, документація JavaScript прямо стосується використання змінних типу Object таким чином, як "асоціативні масиви".


27
2017-08-07 19:52



Не буде працювати, тому що він буде також розраховувати методи, які додаються через прототип. - Lajos Meszaros


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

Object.getOwnPropertyNames({"hi":"Hi","msg":"Message"}).length; // => 2

25
2017-07-01 12:40



Я віддаю перевагу цьому методу, тому що він внутрішньо називає "hasOwnProperty", тому не натискає назви властивостей, які успадковуються від ланцюга прототипів, і це є єдиним лайнером, як і Object.keys(...).length але набагато безпечніше через те, що я тільки що заявив. - Patrick Roberts
Метод клавіші @PatrickRoberts не повертає властивості з ланцюжка прототипів. Так чому потреба в hasOwnProperty тут. Також getOwnProperty поверне приховані властивості, оскільки довжина знаходиться в масиві тощо. - Muhammad Umer
@MuhammadUmer "Якщо у мене є JavaScript асоціативний масив ..." це об'єкт, а не масив. length є властивістю екземпляра Array, тому його слід враховувати в довжині ключів. І так, ви правильні про ланцюг прототипів, я відкликаю це твердження. Що я мав на увазі сказати, це те, що зазвичай ви хочете мати навіть неперераховані властивості, якщо у вас є об'єкт, подібний до не масиву, тому що масив вже матиме length властивість почати. - Patrick Roberts
робить цю роботу в IE-8 - marcusshep


Щоб не перешкоджати прототипу чи іншому коду, ви можете створити та розширити свій власний об'єкт:

function Hash(){
    var length=0;
    this.add = function(key, val){
         if(this[key] == undefined)
         {
           length++;
         }
         this[key]=val;
    }; 
    this.length = function(){
        return length;
    };
}

myArray = new Hash();
myArray.add("lastname", "Simpson");
myArray.add("age", 21);
alert(myArray.length()); // will alert 2

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

Звичайно, ви завжди можете переписати методи. Але навіть якщо ви це зробите, ваш код, ймовірно, не зможе помітно зіткнутися, що полегшить налагодження. ;)


19
2018-06-11 15:44



Я думаю, що це найкраще рішення, оскільки воно не вимагає циклу з "для", що може бути дорогим, якщо масив є великим - Digitlimit