Объект пуст?
Каков самый быстрый способ проверить, является ли объект пустым или нет?
Есть ли более быстрый и лучший способ:
function count_obj(obj){
var i = 0;
for(var key in obj){
++i;
}
return i;
}
Ответы
Ответ 1
Я предполагаю, что пустым вы имеете в виду, что "не имеет собственных свойств".
// Speed up calls to hasOwnProperty
var hasOwnProperty = Object.prototype.hasOwnProperty;
function isEmpty(obj) {
// null and undefined are "empty"
if (obj == null) return true;
// Assume if it has a length property with a non-zero value
// that that property is correct.
if (obj.length > 0) return false;
if (obj.length === 0) return true;
// If it isn't an object at this point
// it is empty, but it can't be anything *but* empty
// Is it empty? Depends on your application.
if (typeof obj !== "object") return true;
// Otherwise, does it have any properties of its own?
// Note that this doesn't handle
// toString and valueOf enumeration bugs in IE < 9
for (var key in obj) {
if (hasOwnProperty.call(obj, key)) return false;
}
return true;
}
Примеры:
isEmpty(""), // true
isEmpty(33), // true (arguably could be a TypeError)
isEmpty([]), // true
isEmpty({}), // true
isEmpty({length: 0, custom_property: []}), // true
isEmpty("Hello"), // false
isEmpty([1,2,3]), // false
isEmpty({test: 1}), // false
isEmpty({length: 3, custom_property: [1,2,3]}) // false
Если вам нужно только обрабатывать браузеры ECMAScript5, вы можете использовать Object.getOwnPropertyNames
вместо hasOwnProperty
:
if (Object.getOwnPropertyNames(obj).length > 0) return false;
Это гарантирует, что даже если объект имеет только неперечислимые свойства isEmpty
, он все равно даст вам правильные результаты.
Ответ 2
Для ECMAScript5 (пока не поддерживается во всех браузерах), вы можете использовать:
Object.keys(obj).length === 0
Ответ 3
EDIT: обратите внимание, что вместо этого вы, вероятно, должны использовать решение ES5, поскольку поддержка ES5 широко распространена в наши дни. Тем не менее, он все еще работает для jQuery.
Простой и кросс-браузерный способ заключается в использовании jQuery.isEmptyObject
:
if ($.isEmptyObject(obj))
{
// do something
}
Подробнее: http://api.jquery.com/jQuery.isEmptyObject/
Однако вам нужен jquery.
Ответ 4
Подчеркивание и lodash каждый имеют удобную функцию isEmpty()
, если вы не возражаете добавить дополнительную библиотеку.
_.isEmpty({});
Ответ 5
Позволяет положить этого ребенка в постель; тестируется в Node, Chrome, Firefox и IE 9, становится очевидным, что для большинства случаев использования:
- (для... in...) - самый быстрый вариант использования!
- Object.keys(obj).length в 10 раз медленнее для пустых объектов
- JSON.stringify(obj).length всегда самый медленный (неудивительно)
- Object.getOwnPropertyNames(obj).length занимает больше времени, чем Object.keys(obj).length может быть намного дольше в некоторых системах.
Эффект нижней линии, используйте:
function isEmpty(obj) {
for (var x in obj) { return false; }
return true;
}
или
function isEmpty(obj) {
for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }
return true;
}
Результаты в Node:
- первый результат:
return (Object.keys(obj).length === 0)
- второй результат:
for (var x in obj) { return false; }...
- третий результат:
for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }...
- следующий результат:
return ('{}' === JSON.stringify(obj))
Тестирование объекта с помощью 0 ключей
0,00018
0.000015
0.000015
0.000324
Тестирование объекта с помощью 1 клавиши
0.000346
0.000458
0.000577
0.000657
Тестирование объекта с помощью двух клавиш
0.000375
0,00046
0.000565
0.000773
Тестирование объекта с 3 ключами
0.000406
0.000476
0.000577
0.000904
Тестирование объекта с 4 ключами
0.000435
0.000487
0.000589
0.001031
Тестирование объекта с 5 ключами
0.000465
0.000501
0.000604
0.001148
Тестирование объекта с 6 ключами
0.000492
0.000511
0.000618
0.001269
Тестирование объекта с помощью 7 ключей
0.000528
0.000527
0.000637
0,00138
Тестирование объекта с помощью 8 ключей
0.000565
0.000538
0.000647
0,00159
Тестирование объекта со 100 ключами
0.003718
0,00243
0.002535
0,01381
Тестирование объекта с 1000 ключами
0,0337
0,0193
0,0194
0,1337
Обратите внимание, что если ваш типичный пример использования проверяет непустой объект с несколькими ключами, и редко вы пытаетесь проверить пустые объекты или объекты с 10 или более ключами, рассмотрите параметр Object.keys(obj).length. - в противном случае используйте более общую (для... в...) реализацию.
Обратите внимание, что Firefox, похоже, имеет более быструю поддержку Object.keys(obj).length и Object.getOwnPropertyNames(obj).length, что делает его лучшим выбором для любого непустого объекта, но все же, когда дело доходит до пустых объектов, (для... in...) просто в 10 раз быстрее.
Мои 2 цента - это то, что Object.keys(obj).length - это плохая идея, поскольку он создает объект ключей, чтобы подсчитать, сколько ключей внутри, чем уничтожает его! Чтобы создать этот объект, ему нужно перекрыть ключи... поэтому зачем использовать его, а не параметр (для... в...):)
var a = {};
function timeit(func,count) {
if (!count) count = 100000;
var start = Date.now();
for (i=0;i<count;i++) func();
var end = Date.now();
var duration = end - start;
console.log(duration/count)
}
function isEmpty1() {
return (Object.keys(a).length === 0)
}
function isEmpty2() {
for (x in a) { return false; }
return true;
}
function isEmpty3() {
for (x in a) { if (a.hasOwnProperty(x)) return false; }
return true;
}
function isEmpty4() {
return ('{}' === JSON.stringify(a))
}
for (var j=0;j<10;j++) {
a = {}
for (var i=0;i<j;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1);
timeit(isEmpty2);
timeit(isEmpty3);
timeit(isEmpty4);
}
a = {}
for (var i=0;i<100;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1);
timeit(isEmpty2);
timeit(isEmpty3);
timeit(isEmpty4, 10000);
a = {}
for (var i=0;i<1000;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1,10000);
timeit(isEmpty2,10000);
timeit(isEmpty3,10000);
timeit(isEmpty4,10000);
Ответ 6
Элегантный способ - использовать клавиши
var myEmptyObj = {};
var myFullObj = {"key":"value"};
console.log(Object.keys(myEmptyObj).length); //0
console.log(Object.keys(myFullObj).length); //1
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
Ответ 7
function isEmpty( o ) {
for ( var p in o ) {
if ( o.hasOwnProperty( p ) ) { return false; }
}
return true;
}
Ответ 8
Удивлен, увидев так много слабых ответов на такой основной вопрос JS... Верхний ответ тоже не подходит по этим причинам:
- он генерирует глобальную переменную
- возвращает
true
в undefined
- использует
for...in
, который сам по себе очень медленный
- функция внутри
for...in
бесполезна - return false
без hasOwnProperty
магия будет работать нормально
На самом деле существует более простое решение:
function isEmpty(value){
return Boolean(value && typeof value == 'object') && !Object.keys(value).length;
});
Ответ 9
https://lodash.com/docs#isEmpty поставляется очень удобно:
_.isEmpty({}) // true
_.isEmpty() // true
_.isEmpty(null) // true
_.isEmpty("") // true
Ответ 10
var x= {}
var y= {x:'hi'}
console.log(Object.keys(x).length===0)
console.log(Object.keys(y).length===0)
true
false
http://jsfiddle.net/j7ona6hz/1/
Ответ 11
Насколько это плохо?
function(obj){
for(var key in obj){
return false; // not empty
}
return true; // empty
}
Ответ 12
Вы можете использовать JSON.stringify(obj)
, а затем сравнить его с пустым объектом. Вот так:
JSON.stringify(your_object)=="{}"
Ответ 13
Нет необходимости в библиотеке.
function(){ //must be within a function
var obj = {}; //the object to test
for(var isNotEmpty in obj) //will loop through once if there is a property of some sort, then
return alert('not empty')//what ever you are trying to do once
return alert('empty'); //nope obj was empty do this instead;
}
Ответ 14
Вот простая функция, которая проверяет, является ли объект пустым (полезно для проверки нарушения ограничений) из кода todomvc src.
var _isEmptyObject = function (obj) {
for (var property in obj)
return false;
return true;
};
И вот пример из angular:
function isObjectEmpty(obj) {
if (obj) {
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
return false;
}
}
}
return true;
}
И один из Ionic:
function isObjectEmpty(obj) {
if (obj) {
for (var prop in obj) {
return false;
}
}
return true;
}
Ответ 15
Это может быть немного взломано. Вы можете попробовать это.
if (JSON.stringify(data).length === 2) {
// Do something
}
Не уверен, есть ли недостаток этого метода.
Ответ 16
быстрый onliner для "словарных" объектов:
function isEmptyDict(d){for (var k in d) return false; return true}
Ответ 17
Вы можете написать резервную копию, если Array.isArray и Object.getOwnPropertyNames недоступны
XX.isEmpty = function(a){
if(Array.isArray(a)){
return (a.length==0);
}
if(!a){
return true;
}
if(a instanceof Object){
if(a instanceof Date){
return false;
}
if(Object.getOwnPropertyNames(a).length == 0){
return true;
}
}
return false;
}
Ответ 18
Представьте, что у вас есть следующие объекты:
var obj1= {};
var obj2= {test: "test"};
Не забывайте, что мы не можем использовать знак === для проверки равенства объектов, поскольку они наследуют, поэтому, если вы используете ECMA 5 и верхнюю версию javascript, ответ прост, вы можете использовать следующую функцию:
function isEmpty(obj) {
//check if it an Obj first
var isObj = obj !== null
&& typeof obj === 'object'
&& Object.prototype.toString.call(obj) === '[object Object]';
if (isObj) {
for (var o in obj) {
if (obj.hasOwnProperty(o)) {
return false;
break;
}
}
return true;
} else {
console.error("isEmpty function only accept an Object");
}
}
чтобы результат был следующим:
isEmpty(obj1); //this returns true
isEmpty(obj2); //this returns false
isEmpty([]); // log in console: isEmpty function only accept an Object
Ответ 19
Я немного поиграл и получил это:
jQuery.isBlank = function (obj) {
if (!obj || jQuery.trim(obj) === "") return true;
if (obj.length && obj.length > 0) return false;
for (var prop in obj) return false;
return true;
};
console.log(
$.isBlank(0), // true
$.isBlank(""), // true
$.isBlank(null), // true
$.isBlank(false), // true
$.isBlank(undefined), // true
$.isBlank([]), // true
$.isBlank([null]), // true
$.isBlank([undefined]), // true
$.isBlank({}), // true
$.isBlank({foo: 0}), // false
$.isBlank({foo: null}), // false
$.isBlank({foo: false}), // false
$.isBlank({foo: undefined}), // false
$.isBlank("Hello"), // false
$.isBlank([1,2,3]), // false
$.isBlank({foo: 1}), // false
$.isBlank({foo: 3, bar: [1,2,3]}), // false
"incorrect:",
$.isBlank(1), // true
$.isBlank(true), // true
$.isBlank([0]), // false
$.isBlank([false]), // false
$.isBlank("0"), // false
$.isBlank(["0"]), // false
$.isBlank({foo: "0"}) // false
);
Получилось вдохновение отсюда:
https://gist.github.com/laktek/758269#comment-784188
Ответ 20
Может быть, вы можете использовать это решение:
var isEmpty = function(obj) {
for (var key in obj)
if(obj.hasOwnProperty(key))
return false;
return true;
}
Ответ 21
здесь хороший способ сделать это
function isEmpty(obj) {
if (Array.isArray(obj)) {
return obj.length === 0;
} else if (typeof obj === 'object') {
for (var i in obj) {
return false;
}
return true;
} else {
return !obj;
}
}
Ответ 22
var hasOwnProperty = Object.prototype.hasOwnProperty;
function isArray(a) {
return Object.prototype.toString.call(a) === '[object Array]'
}
function isObject(a) {
return Object.prototype.toString.call(a) === '[object Object]'
}
function isEmpty(a) {
if (null == a || "" == a)return!0;
if ("number" == typeof a || "string" == typeof a)return!1;
var b = !0;
if (isArray(a)) {
if (!a.length)return!0;
for (var c = 0; c < a.length; c++)isEmpty(a[c]) || (b = !1);
return b
}
if (isObject(a)) {
for (var d in a)hasOwnProperty.call(a, d) && (isEmpty(a[d]) || (b = !1));
return b
}
return!0
}
Ответ 23
Я изменил код Шона Виейры в соответствии с моими потребностями. null и undefined не считаются объектом вообще, а числа, логические значения и пустые строки возвращают false.
'use strict';
// Speed up calls to hasOwnProperty
var hasOwnProperty = Object.prototype.hasOwnProperty;
var isObjectEmpty = function(obj) {
// null and undefined are not empty
if (obj == null) return false;
if(obj === false) return false;
if(obj === true) return false;
if(obj === "") return false;
if(typeof obj === "number") {
return false;
}
// Assume if it has a length property with a non-zero value
// that that property is correct.
if (obj.length > 0) return false;
if (obj.length === 0) return true;
// Otherwise, does it have any properties of its own?
// Note that this doesn't handle
// toString and valueOf enumeration bugs in IE < 9
for (var key in obj) {
if (hasOwnProperty.call(obj, key)) return false;
}
return true;
};
exports.isObjectEmpty = isObjectEmpty;
Ответ 24
объект является ассоциативным массивом, дополненным прототипом.
Метод Object.is() определяет, являются ли два значения одинаковыми.
сравнение объектов: -
Object.is('LOL', 'LOL');// true
Object.is(console, console);// true
Object.is(null, null);// true
Object.is('ROFL', 'LOL');// false
Object.is([], []);// false
Object.is(0, -0);// false
Object.is(NaN, 0/0);// true
if (!Object.is)
{
// do something
}
Ответ 25
funtion isEmpty(o,i)
{
for(i in o)
{
return!1
}
return!0
}
Ответ 26
if (Object.getOwnPropertyNames(obj1).length > 0)
{
alert('obj1 is empty!');
}
Ответ 27
здесь мое решение
function isEmpty(value) {
if(Object.prototype.toString.call(value) === '[object Array]') {
return value.length == 0;
} else if(value != null && typeof value === 'object') {
return Object.getOwnPropertyNames(value).length == 0;
} else {
return !(value || (value === 0));
}
}
Стулья