Если у меня есть объект 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(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
Обновлено. Если вы используете 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;
};
_.size()
было идеальным решением для моего проекта Meteor , который имеет поддержку underscore.js.
Используйте что-то простое:
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;
Object.keys()
возвращает массив, содержащий имена только тех свойств, которые можно перечислить. Если вам нужен массив со ВСЕМИ свойствами, вы должны использовать Object.getOwnPropertyNames()
. См. Developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Я не эксперт по JavaScript, но похоже, вам придется перебирать элементы и подсчитывать их, поскольку Object не имеет метода длины:
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 будет правильным. Если вы беспокоитесь о том, что вы или другие люди забыли о его использовании, вы можете добавить счетчик свойств, который другие отправили также методу длины.
Конечно, вы всегда можете переписать методы. Но даже если вы это сделаете, ваш код, вероятно, не удастся заметно, что упростит его отладку.;)
Вот как и не забывайте проверить, что свойство не находится в цепочке прототипов:
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
Установите класс ассоциативной матрицы
/**
* @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);
length
, любой код, который использовал его, должен был бы гарантировать, что оно не будет пытаться сохранить против length
, но я думаю, что это будет то же самое, если это был стандартный массив тоже. Переопределение hasOwnProperty
для любого объекта, скорее всего, приведет к нежелательному результату.
В некоторых случаях лучше просто сохранить размер в отдельной переменной. Особенно, если вы добавляете массив к одному элементу в одном месте и можете легко увеличивать размер. Очевидно, что это будет работать намного быстрее, если вам нужно часто проверять размер.
Самый простой
Object.keys(myObject).length
Использование:
var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
obj = Object.keys(myArray).length;
console.log(obj)
Просто используйте это, чтобы получить length
:
Object.keys(myObject).length
myArray
@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 и проверить тип членов при прохождении через них.
Если вы используете 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>
Если у нас есть хеш
hash = { "a": "b", "c": "d" };
мы можем получить длину, используя длину ключей, которая является длиной хеша:
клавиши (хэш).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--; }}
}
Если вам нужна ассоциативная структура данных, которая раскрывает ее размер, лучше используйте карту вместо объекта.
var myMap = new Map();
myMap.set("firstname", "Gareth");
myMap.set("lastname", "Simpson");
myMap.set("age", 21);
myMap.size; // 3
<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;
Если вам не нужна поддержка 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
См. также этот скрипт для демонстрации.
Вариант для некоторых из вышеперечисленных вариантов:
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.prototype
- плохая идея.
Самый простой способ такой
Object.keys(myobject).length
где myobject - это объект того, что вы хотите, чтобы длина
Вы можете просто использовать 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()
var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
Вы всегда можете сделать Object.getOwnPropertyNames(myObject).length
, чтобы получить тот же результат, что и [].length
для нормального массива.
Object.keys()
возвращает массив, содержащий имена только тех свойств, которые можно перечислить. Если вам нужен массив со ВСЕМИ свойствами, вы должны использовать Object.getOwnPropertyNames()
. См. Developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Немного поздно в игре, но хороший способ добиться этого (только для IE9 +) - определить магический getter на свойстве length:
Object.defineProperty(Object.prototype, "length", {
get: function () {
return Object.keys(this).length;
}
});
И вы можете просто использовать его так:
var myObj = { 'key': 'value' };
myObj.length;
Давал бы 1
.
Мы можем найти длину объекта, используя:
Object.values(myObject).length
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
Как и большинство проблем с JavaScript, существует множество решений. Вы можете расширить объект, который лучше или хуже работает, как и словарь многих других языков (+ граждане первого класса). В этом нет ничего плохого, но еще один вариант - создать новый объект, соответствующий вашим конкретным потребностям.
function uberject(obj){
this._count = 0;
for(var param in obj){
this[param] = obj[param];
this._count++;
}
}
uberject.prototype.getLength = function(){
return this._count;
};
var foo = new uberject({bar:123,baz:456});
alert(foo.getLength());
Ниже приведена версия ответа Джеймса Коглана в CoffeeScript для тех, кто отказался от прямого JavaScript:)
Object.size = (obj) ->
size = 0
size++ for own key of obj
size
size++ for own key of obj
( own key
является синтаксическим сахаром в CoffeeScript). Использование hasOwnProperty
непосредственно из объекта опасно, так как оно прерывается, когда объект действительно обладает таким свойством.
var obj = {
key1: "value1",
key2: "value2",
key3: "value3"
}
// use any of these to find object length
* Object.keys(obj).length
* Object.values(obj).length
* Object.entries(obj).length
В лучшем случае, на мой взгляд, if (obj.hasOwnProperty(key))
элемент управления является избыточным. Возвращает всегда true
.
Object.size = function(obj) {
var size = 0, key;
for (key in obj) {
size++;
}
return size;
};
hasOwnProperty
используется, состоит в том, чтобы предотвратить подсчет ключей в его прототипе. Пример: parent = {a: 1, b:2}; child = Object.create(parent); Object.keys(child) === 0; Object.size(child) === 2;
, Это использует ваш Object.size
, а не правильный.
Решение работает во многих случаях и в браузере:
код
var getTotal = function(collection) {
var length = collection['length'];
var isArrayObject = typeof length == 'number' && length >= 0 && length <= Math.pow(2,53) - 1; // Number.MAX_SAFE_INTEGER
if(isArrayObject) {
return collection['length'];
}
i= 0;
for(var key in collection) {
if (collection.hasOwnProperty(key)) {
i++;
}
}
return i;
};
Примеры данных:
// case 1
var a = new Object();
a["firstname"] = "Gareth";
a["lastname"] = "Simpson";
a["age"] = 21;
//case 2
var b = [1,2,3];
// case 3
var c = {};
c[0] = 1;
c.two = 2;
Использование
getLength(a); // 3
getLength(b); // 3
getLength(c); // 2
Простое решение:
var myObject = {}; // ... your object goes here.
var length = 0;
for (var property in myObject) {
if (myObject.hasOwnProperty(property)){
length += 1;
}
};
console.log(length); // logs 0 in my example.
var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
var size = JSON.stringify(myObject).length;
document.write(size);
JSON.stringify(myObject)
Если вы используете jQuery, просто перейдите к методу .length
.
$(object).length
даст вам длину переданного объекта.
UPDATE. Это всегда будет возвращать 1 в случае объекта. Но хорошо работает с элементом jQuery.