Вопрос:

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

javascript javascript-objects

1607580 просмотра

30 ответа

15235 Репутация автора

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

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

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

Автор: Gareth Simpson Источник Размещён: 07.08.2008 07:42

Ответы (30)


34 плюса

6148 Репутация автора

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

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

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

Автор: jj33 Размещён: 07.08.2008 07:52

18 плюса

9514 Репутация автора

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

var element_count = 0;
for(var e in myArray)
    if(myArray.hasOwnProperty(e))
        element_count++;
Автор: doekman Размещён: 08.08.2008 07:18

14 плюса

16920 Репутация автора

@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 и проверять тип членов при их итерации по ним.

Автор: Polsonby Размещён: 08.08.2008 10:34

2370 плюса

0 Репутация автора

Решение

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

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(myObj);

В 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
Автор: James Coglan Размещён: 09.08.2008 08:31

1579 плюса

16087 Репутация автора

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

Object.keys(myArray).length
Автор: aeosynth Размещён: 03.04.2011 01:44

24 плюса

8937 Репутация автора

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

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 будет правильным. Если вы беспокоитесь о том, что вы или другие забыли об его использовании, вы можете добавить счетчик свойств, который другие опубликовали, также в методе length.

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

Автор: DanMan Размещён: 11.06.2011 03:44

15 плюса

1123 Репутация автора

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

Автор: Jānis Elmeris Размещён: 29.07.2011 01:41

11 плюса

111 Репутация автора

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

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--; }}
}
Автор: Jerry Размещён: 24.08.2011 02:26

7 плюса

71 Репутация автора

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

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

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

Автор: wade harrell Размещён: 18.11.2011 06:06

273 плюса

95088 Репутация автора

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

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

Если нет , и вы не хотите возиться со свойствами объекта по какой-либо причине и уже используете 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;
};
Автор: ripper234 Размещён: 05.07.2012 02:39

3 плюса

2654 Репутация автора

Ниже приведена версия ответа Джеймса Коглана в CoffeeScript для тех, кто отказался от прямого JavaScript :)

Object.size = (obj) ->
  size = 0
  size++ for own key of obj
  size
Автор: Eric Anderson Размещён: 04.03.2013 05:38

6 плюса

2610 Репутация автора

Вот другая версия ответа Джеймса Когана. Вместо передачи аргумента просто создайте прототип класса 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/

Автор: Sherzod Размещён: 26.06.2013 11:47

16 плюса

3313 Репутация автора

Это совершенно другое решение, которое будет работать только в более современных браузерах (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);
Автор: Ally Размещён: 02.08.2013 08:49

52 плюса

4108 Репутация автора

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

Это лучше, чем принятый ответ, потому что он использует нативный 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;
Автор: Joon Размещён: 01.09.2013 04:12

11 плюса

1316 Репутация автора

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

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

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

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

Автор: abo-elleef Размещён: 09.02.2014 06:48

30 плюса

1743 Репутация автора

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

Object.getOwnPropertyNames({"hi":"Hi","msg":"Message"}).length; // => 2
Автор: venkat7668 Размещён: 01.07.2014 12:40

3 плюса

10601 Репутация автора

Имущество

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

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

var o = {a: 1, b: 2, c: 3};
alert(o.length); // <-- 3
o['foo'] = 123;
alert(o.length); // <-- 4
Автор: Eduardo Cuomo Размещён: 06.01.2015 07:10

10 плюса

1019 Репутация автора

Если вы используете 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>
Автор: pcnate Размещён: 15.09.2015 07:15

5 плюса

1906 Репутация автора

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

Автор: Pian0_M4n Размещён: 12.01.2016 01:37

8 плюса

30393 Репутация автора

Если вам не нужна поддержка 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

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

Автор: John Slegers Размещён: 07.03.2016 01:13

9 плюса

171614 Репутация автора

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

var myMap = new Map();
myMap.set("firstname", "Gareth");
myMap.set("lastname", "Simpson");
myMap.set("age", 21);
myMap.size; // 3
Автор: Oriol Размещён: 18.05.2016 06:16

15 плюса

952 Репутация автора

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

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

Автор: Mahendra Kulkarni Размещён: 31.05.2016 04:49

5 плюса

968 Репутация автора

Вы можете просто использовать Object.keys(obj).lengthлюбой объект, чтобы получить его длину. Object.keys возвращает массив, содержащий все ключи объекта (свойства), которые могут пригодиться для определения длины этого объекта, используя длину соответствующего массива. Вы даже можете написать функцию для этого. Давайте проявим творческий подход и напишем для него метод (вместе с более удобным свойством getter):

function objLength(obj)
{
  return Object.keys(obj).length;
}

console.log(objLength({a:1, b:"summit", c:"nonsense"}));

// Works perfectly fine
var obj = new Object();
obj['fish'] = 30;
obj['nullified content'] = null;
console.log(objLength(obj));

// It also works your way, which is creating it using the Object constructor
Object.prototype.getLength = function() {
   return Object.keys(this).length;
}
console.log(obj.getLength());

// You can also write it as a method, which is more efficient as done so above

Object.defineProperty(Object.prototype, "length", {get:function(){
    return Object.keys(this).length;
}});
console.log(obj.length);

// probably the most effictive approach is done so and demonstrated above which sets a getter property called "length" for objects which returns the equivalent value of getLength(this) or this.getLength()

Автор: Eternal Darkness Размещён: 17.09.2016 01:48

4 плюса

1744 Репутация автора

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

Object.values(myObject).length
Автор: solanki... Размещён: 22.05.2017 01:42

4 плюса

1342 Репутация автора

Немного опоздал к игре, но хороший способ добиться этого (только для IE9 +) - определить магический метод получения свойства length:

Object.defineProperty(Object.prototype, "length", {
    get: function () {
        return Object.keys(this).length;
    }
});

И вы можете просто использовать его так:

var myObj = { 'key': 'value' };
myObj.length;

Дал бы 1.

Автор: MacroMan Размещён: 04.07.2017 03:20

18 плюса

807 Репутация автора

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

Object.keys(myObject).length
Автор: saurabhgoyal795 Размещён: 18.01.2018 10:29

9 плюса

362 Репутация автора

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
Автор: tdjprog Размещён: 05.04.2018 11:45

7 плюса

451 Репутация автора

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

Object.keys(myobject).length

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

Автор: Mithu A Quayium Размещён: 30.05.2018 03:41

11 плюса

8355 Репутация автора

<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>

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

var size = Object.keys(myObj).length;
Автор: Giovanni Python Размещён: 06.06.2018 06:51

28 плюса

642 Репутация автора

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

Object.keys(myObject).length
Автор: Tamesh Размещён: 21.06.2018 02:25
Вопросы из категории :
32x32