У меня есть объект JavaScript, есть ли встроенный или общепринятый способ получения длины этого объекта?
var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
У меня есть объект 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. Таким образом, ответ будет неполным, не упоминая их.
Тип символа был добавлен в язык для создания уникальных идентификаторов для свойств объекта. Основным преимуществом типа 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
Обновлено. Если вы используете 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(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;
Я не эксперт по JavaScript, но похоже, вам придется перебирать элементы и подсчитывать их, поскольку Object не имеет метода длины:
var element_count = 0;
for (e in myArray) { if (myArray.hasOwnProperty(e)) element_count++; }
@palmsey: В справедливости к OP документация JavaScript на самом деле явно ссылается на использование переменных типа Object таким образом как "ассоциативные массивы".
Самый простой
Object.keys(myObject).length
Этот метод получает все ваши имена свойств объекта в массиве, поэтому вы можете получить длину этого массива, которая равна длине ваших объектов.
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 будет правильным. Если вы беспокоитесь о том, что вы или другие люди забыли о его использовании, вы можете добавить счетчик свойств, который другие отправили также методу длины.
Конечно, вы всегда можете переписать методы. Но даже если вы это сделаете, ваш код, вероятно, не удастся заметно, что упростит его отладку.;)
Вот как и не забывайте проверить, что свойство не находится в цепочке прототипов:
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 "Ассоциативные массивы" считается вредным
Но по всем этим, не является ли принятым ответом плохая практика?
Укажите функцию prototype size() для Object
Если что-то еще добавлено в 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>
Я не думаю, что ответ должен быть принят, так как нельзя доверять работе, если у вас есть другой код, работающий в том же контексте выполнения. Чтобы сделать это в надежной манере, вам нужно будет определить метод размера в myArray и проверить тип членов при прохождении через них.
<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>
Что-то вроде этого -
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--; }}
}
Если у нас есть хеш
hash = { "a": "b", "c": "d" };
мы можем получить длину, используя длину ключей, которая является длиной хеша:
клавиши (хэш).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>
Если вам нужна ассоциативная структура данных, которая раскрывает ее размер, лучше используйте карту вместо объекта.
var myMap = new Map();
myMap.set("firstname", "Gareth");
myMap.set("lastname", "Simpson");
myMap.set("age", 21);
myMap.size; // 3
var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
Если вам не нужна поддержка Internet Explorer 8 или ниже, вы можете легко получить количество свойств в объекте, выполнив следующие два шага:
Object.keys()
, чтобы получить массив, содержащий имена только тех свойств, которые перечисляемый или Object.getOwnPropertyNames()
, если вы хотите также включить имена свойств, которые не перечислены..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
См. также этот скрипт для демонстрации.
Самый простой способ такой
Object.keys(myobject).length
где myobject - это объект того, что вы хотите, чтобы длина
Вариант для некоторых из вышеперечисленных вариантов:
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
для нормального массива.
Вы можете просто использовать 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()
Мы можем найти длину объекта, используя:
Object.values(myObject).length
Немного поздно в игре, но хороший способ добиться этого (только для IE9 +) - определить магический getter на свойстве length:
Object.defineProperty(Object.prototype, "length", {
get: function () {
return Object.keys(this).length;
}
});
И вы можете просто использовать его так:
var myObj = { 'key': 'value' };
myObj.length;
Давал бы 1
.
Ниже приведена версия ответа Джеймса Коглана в CoffeeScript для тех, кто отказался от прямого JavaScript:)
Object.size = (obj) ->
size = 0
size++ for own key of obj
size