Длина объекта JavaScript

Если у меня есть объект JavaScript, скажем

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

Есть ли встроенный или общепринятый способ получения длины этого объекта?

48 ответов

Решение

Самый надежный ответ (то есть, который отражает намерение того, что вы пытаетесь сделать, вызывая при этом наименьшее количество ошибок), был бы:

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, потому что он может нарушать перечисления в различных библиотеках. Однако добавление методов в Object обычно безопасно.


Вот обновление от 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

Если вы знаете, вам не нужно беспокоиться о hasOwnProperty проверки, вы можете сделать это очень просто:

Object.keys(myArray).length

Обновлено: если вы используете http://underscorejs.org/ (рекомендуется, он легкий!), То вы можете просто сделать

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

Если нет, и вы не хотите возиться со свойствами объекта по какой-либо причине и уже используете jQuery, плагин одинаково доступен:

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

Используйте что-то простое, как:

Object.keys(obj).length

Это не должно быть сложно и определенно не требует выполнения другой функции.

Вот самое кросс-браузерное решение.

Это лучше, чем принятый ответ, потому что он использует нативные 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;

Просто используйте это, чтобы получить length:

Object.keys(myObject).length

Я не эксперт по JavaScript, но похоже, что вам придется циклически проходить по элементам и считать их, поскольку у Object нет метода length:

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

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

Этот метод получает все имена свойств вашего объекта в массиве, поэтому вы можете получить длину этого массива, равную длине ключей вашего объекта.

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

Чтобы не связываться с прототипом или другим кодом, вы можете создать и расширить свой собственный объект:

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

Если вы всегда используете метод add, свойство length будет правильным. Если вы беспокоитесь о том, что вы или другие забыли об его использовании, вы можете добавить счетчик свойств, который другие разместили в методе длины.

Конечно, вы всегда можете переписать методы. Но даже если вы это сделаете, ваш код, вероятно, заметно потерпит неудачу, упрощая отладку.;)

Мы можем найти длину объекта с помощью:

Object.values(myObject).length

Вот как и не забудьте проверить, что свойство не входит в цепочку прототипов:

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

Это совершенно другое решение, которое будет работать только в более современных браузерах (IE9+, Chrome, Firefox 4+, Opera 11.60+, Safari 5.1+).

Смотрите jsFiddle

Настройте свой ассоциативный класс Array

/**
 * @constructor
 */
AssociativeArray = function () {};

// Make the length property work
Object.defineProperty(AssociativeArray.prototype, "length", {
    get: function () {
        var count = 0;
        for (var key in this) {
            if (this.hasOwnProperty(key))
                count++;
        }
        return count;
    }
});

Теперь вы можете использовать этот код следующим образом...

var a1 = new AssociativeArray();
a1["prop1"] = "test";
a1["prop2"] = 1234;
a1["prop3"] = "something else";
alert("Length of array is " + a1.length);

Если вам нужна ассоциативная структура данных, которая показывает ее размер, лучше использовать карту вместо объекта.

var myMap = new Map();
myMap.set("firstname", "Gareth");
myMap.set("lastname", "Simpson");
myMap.set("age", 21);
myMap.size; // 3

Использовать Object.keys(myObject).length чтобы получить длину объекта / массива

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

console.log(Object.keys(myObject).length); //3

Использование:

var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
obj = Object.keys(myArray).length;
console.log(obj)

<script>
myObj = {"key1" : "Hello", "key2" : "Goodbye"};
var size = Object.keys(myObj).length;
console.log(size);
</script>

<p id="myObj">The number of <b>keys</b> in <b>myObj</b> are: <script>document.write(size)</script></p>
<p style="font-size:0.6em;">P.S.: If you want to learn Python and have fun go here <a href="https://pythonprogramming.altervista.org/">https://pythonprogramming.altervista.org/</a>
</p>

Это работает для меня:

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

Самый простой способ такой

Object.keys(myobject).length

где myobject - это объект того, что вы хотите, чтобы длина

В некоторых случаях лучше просто сохранить размер в отдельной переменной. Особенно, если вы добавляете в массив по одному элементу в одном месте и можете легко увеличить размер. Очевидно, это будет работать намного быстрее, если вам нужно часто проверять размер.

@palmsey: справедливости для OP, документы javascript фактически явно ссылаются на использование переменных типа Object таким образом, как "ассоциативные массивы".

И, честно говоря, @palmsey он был совершенно прав: они не ассоциативные массивы, а определенно объекты:) - выполняющие работу ассоциативного массива. Но что касается более широкой темы, вы определенно имеете на это право в соответствии с этой довольно хорошей статьей, которую я нашел:

JavaScript "Ассоциативные массивы" считается вредным

Но в соответствии с этим, не является ли принятый ответ самой плохой практикой?

Укажите функцию прототипа size() для объекта

Если что-то еще было добавлено в Object.prototype, то предложенный код завершится ошибкой:

<script type="text/javascript">
Object.prototype.size = function () {
  var len = this.length ? --this.length : -1;
    for (var k in this)
      len++;
  return len;
}
Object.prototype.size2 = function () {
  var len = this.length ? --this.length : -1;
    for (var k in this)
      len++;
  return len;
}
var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
alert("age is " + myArray["age"]);
alert("length is " + myArray.size());
</script>

Я не думаю, что ответ должен быть принят, так как ему нельзя доверять, если у вас есть другой код, работающий в том же контексте выполнения. Чтобы сделать это надежным способом, вам необходимо определить метод size в myArray и проверять тип элементов при их итерации.

С использованием Object.entriesметод получения длины - это один из способов ее достижения

Если у нас есть хэш

hash = {"a": "b", "c": "d"};

мы можем получить длину, используя длину ключей, которая является длиной хеша:

ключи (хэш).length

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
  1. Object.values ​​(MyObject).length
  2. Object.entries (MyObject).length
  3. Object.keys (MyObject).length

Как насчет чего-то вроде этого -

function keyValuePairs() {
    this.length = 0;
    function add(key, value) { this[key] = value; this.length++; }
    function remove(key) { if (this.hasOwnProperty(key)) { delete this[key]; this.length--; }}
}

Если вы используете AngularJS 1.x, вы можете делать вещи AngularJS путем создания фильтра и использования кода из любого другого примера, такого как следующее:

// Count the elements in an object
app.filter('lengthOfObject', function() {
  return function( obj ) {
    var size = 0, key;
    for (key in obj) {
      if (obj.hasOwnProperty(key)) size++;
    }
   return size;
 }
})

использование

В вашем контроллере:

$scope.filterResult = $filter('lengthOfObject')($scope.object)

Или по вашему мнению:

<any ng-expression="object | lengthOfObject"></any>
const myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

console.log(Object.keys(myObject).length)

// o/p 3

Самый простой

Object.keys(myObject).length

Если вам не нужна поддержка Internet Explorer 8 или ниже, вы можете легко получить количество свойств в объекте, выполнив следующие два шага:

  1. Запустить либо Object.keys() получить массив, который содержит имена только тех свойств, которые перечисляются или Object.getOwnPropertyNames() если вы хотите также включить имена свойств, которые не перечисляются.
  2. Получить .length свойство этого массива.

Если вам нужно сделать это более одного раза, вы можете заключить эту логику в функцию:

function size(obj, enumerablesOnly) {
    return enumerablesOnly === false ?
        Object.getOwnPropertyNames(obj).length :
        Object.keys(obj).length;
}

Как использовать эту функцию:

var myObj = Object.create({}, {
    getFoo: {},
    setFoo: {}
});
myObj.Foo = 12;

var myArr = [1,2,5,4,8,15];

console.log(size(myObj));        // Output : 1
console.log(size(myObj, true));  // Output : 1
console.log(size(myObj, false)); // Output : 3
console.log(size(myArr));        // Output : 6
console.log(size(myArr, true));  // Output : 6
console.log(size(myArr, false)); // Output : 7

Смотрите также эту скрипку для демонстрации.

Вариация некоторых из вышеперечисленных:

var objLength = function(obj){    
    var key,len=0;
    for(key in obj){
        len += Number( obj.hasOwnProperty(key) );
    }
    return len;
};

Это немного более элегантный способ интеграции hasOwnProp.

Вот другая версия ответа Джеймса Когана. Вместо передачи аргумента просто создайте прототип класса Object и сделайте код чище.

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

var x = {
    one: 1,
    two: 2,
    three: 3
};

x.size() === 3;

Пример jsfiddle: http://jsfiddle.net/qar4j/1/

Вы всегда можете сделать Object.getOwnPropertyNames(myObject).length получить тот же результат, что и [].length дал бы для нормального массива.

Другие вопросы по тегам