Сведения о вопросе

Henry

16:03, 1st July, 2020

Теги

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

Просмотров: 610   Ответов: 25

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

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

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



  Сведения об ответе

screen

18:03, 1st July, 2020

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

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


Вот обновление от 2016 года и широко распространенное deployment из ES5 и за его пределами. Для IE9+ и всех других современных браузеров с поддержкой ES5+ вы можете использовать Object.keys() , поэтому приведенный выше код просто становится:

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

Это не должно изменить ни один существующий прототип, так как Object.keys() теперь встроен.

Edit: объекты могут иметь символические свойства, которые не могут быть возвращены с помощью метода 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


  Сведения об ответе

appple

18:03, 1st July, 2020

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

Object.keys(myArray).length


  Сведения об ответе

LAST

18:03, 1st July, 2020

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


  Сведения об ответе

P_S_S

18:03, 1st July, 2020

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

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


  Сведения об ответе

VCe znayu

18:03, 1st July, 2020

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

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

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


  Сведения об ответе

padenie

18:03, 1st July, 2020

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

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


  Сведения об ответе

ITSME

18:03, 1st July, 2020

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

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

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


  Сведения об ответе

#hash

18:03, 1st July, 2020

Самый простой из них-это

Object.keys(myObject).length


  Сведения об ответе

park

18:03, 1st July, 2020

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

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


  Сведения об ответе

dump

18:03, 1st July, 2020

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

Object.keys(myObject).length


  Сведения об ответе

baggs

18:03, 1st July, 2020

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


  Сведения об ответе

dump

18:03, 1st July, 2020

Вот совершенно другое решение, которое будет работать только в более современных браузерах (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);


  Сведения об ответе

$DOLLAR

18:03, 1st July, 2020

Воспользуйся:

var myArray = new Object();

myArray["firstname"] = "Gareth";

myArray["lastname"] = "Simpson";

myArray["age"] = 21;

obj = Object.keys(myArray).length;

console.log(obj)


  Сведения об ответе

P_S_S

18:03, 1st July, 2020

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

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

JavaScript “Associative Arrays” Считается Вредным

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

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

Если что-то еще было добавлено в объект .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>

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


  Сведения об ответе

darknet

18:03, 1st July, 2020

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

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


  Сведения об ответе

darknet

18:03, 1st July, 2020

Если у нас есть hash

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

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

ключи(hash).длина


  Сведения об ответе

appple

18:03, 1st July, 2020

Если вы используете 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>


  Сведения об ответе

pumpa

18:03, 1st July, 2020

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

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


  Сведения об ответе

P_S_S

18:03, 1st July, 2020

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


  Сведения об ответе

park

18:03, 1st July, 2020

Одним из вариантов некоторых из вышеперечисленных является:

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

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


  Сведения об ответе

ASER

18:03, 1st July, 2020

Если вы не заботитесь о поддержке 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

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


  Сведения об ответе

VCe znayu

18:03, 1st July, 2020

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
  1. Object.values(myObject).длина
  2. Object.entries(myObject).длина
  3. Object.keys(myObject).длина


  Сведения об ответе

baggs

18:03, 1st July, 2020

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

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/


  Сведения об ответе

SILA

18:03, 1st July, 2020

Вы можете просто использовать 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()


  Сведения об ответе

PROGA

18:03, 1st July, 2020

Самый простой способ выглядит так

Object.keys(myobject).length

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться