Вопрос

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

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

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

Это было полезно?

Решение

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

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.Поэтому без упоминания о них ответ будет неполным.

Тип символа был добавлен в язык для создания уникальных идентификаторов свойств объектов.Основным преимуществом типа «Символ» является предотвращение перезаписи.

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

Обновлено:Если вы используете 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;
};

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

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

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

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

@palmsey:Справедливости ради ОП, в документации 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.keys(myObject).length

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

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

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

Object.keys(myObject).length

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

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

Видеть jsFiddle

Настройте свой класс ассоциативного массива

/**
 * @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 myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
obj = Object.keys(myArray).length;
console.log(obj)

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

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

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>

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

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

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

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

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

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

Если вас не интересует поддержка 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 myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
  1. Object.values(myObject).length
  2. Object.entries(myObject).длина
  3. Object.keys(myObject).длина

Вот другая версия ответа Джеймса Когана.Вместо передачи аргумента просто создайте прототип класса 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.keys(obj).length на любом объекте, чтобы получить его длину.Object.keys возвращает массив, содержащий весь объект. ключи (свойства), которые могут пригодиться для определения длины этого объекта по длине соответствующего массива.Вы даже можете написать функция для этого.Давай творческий и напиши метод и для него (вместе с более удобным свойством получения):

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

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

Object.keys(myobject).length

где myobject — это объект желаемой длины

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

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

Object.size = (obj) ->
  size = 0
  size++ for own key of obj
  size

Свойство

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

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

Object.values(myObject).length

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

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

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

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

Даст 1.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top