Как проверить, есть ли у объекта какие-либо свойства в JavaScript?

168

Предполагая, что я заявляю

var ad = {}; 

Как я могу проверить, будет ли этот объект содержать какие-либо пользовательские свойства?

Рики
источник

Ответы:

86

Вы можете зациклить свойства вашего объекта следующим образом:

for(var prop in ad) {
    if (ad.hasOwnProperty(prop)) {
        // handle prop as required
    }
}

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

редактировать

Из комментариев: Вы можете поместить этот код в функцию и заставить его возвращать false, как только он достигнет той части, где находится комментарий

Тест производительности

Test Of Object.Keys vs For..In При тестировании любых свойств

Даниэль Вассалло
источник
2
Привет, Даниэль, на самом деле я ищу устройство, чтобы проверить, содержит ли объект определенные пользователем свойства или нет. Не проверять, существует ли конкретное свойство.
Рики
7
@Ricky: Вы можете поместить этот код в функцию и заставить его возвращать false, как только он достигнет той части, где находится комментарий.
Даниэль Вассалло
8
Я думаю, что в наши дни использовать Object.keysбыло бы проще всего: var a = [1,2,3];a.something=4;console.log(Object.keys(a))поскольку это уже часть ECMA 5, вы можете смело использовать его: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
HMR
2
Обратите внимание, что «в наши дни» в ES5 нативные объекты могут иметь не перечисляемые собственные свойства, например Object.defineProperty(obj, 'foo', {enumerable:false, value:'foo'}).
RobG
2
Это решение является способом проверки существующих ключей , но верный, эффективный и наиболее правильный ответ приведен ниже с использованием Object.keys (x) .length. Вам не нужно создавать свою собственную функцию, она уже существует!
dudewad
197

Вы можете использовать встроенный Object.keysметод, чтобы получить список ключей объекта и проверить его длину.

var x = {};
// some code where value of x changes and than you want to check whether it is null or some object with values

if(Object.keys(x).length > 0){
 // Your code here if x has some properties  
}
Давал Чаудхари
источник
14
Это правильный ответ. Принятый ответ выше - это обходной путь, который стоит дороже, чем просто проверка количества ключей; это имеет больше смысла .
dudewad
6
Object.keys ( "MyString"); также дает ключи, которые я считаю нежелательными. Этот ответ неполон на мой взгляд.
Майк де Клерк
2
@MikedeKlerk, пожалуйста, прочитайте его внимательно, это не Object.keys ("mystring"); это Object.keys (objectVariableName), который будет возвращать массив всех ключей в объекте. например: {'x': 'abc', 'y': 'def'} это будет ['x', 'y']
Давал Чаудхари
3
@DhavalChaudhary Спасибо за ваш ответ на мой комментарий. Когда я пробую этот код var str = "MyString"; Object.keys(str);, консоль выводит 8 клавиш от 0 до 7 для каждого символа. Или я до сих пор не понимаю ответ.
Майк де Клерк
6
@MikedeKlerk, но это только решение для объектов, а не для строк, пожалуйста, обратитесь к вопросу.
Давал Чаудхари
111

Как насчет создания простой функции?

function isEmptyObject(obj) {
  for(var prop in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
      return false;
    }
  }
  return true;
}

isEmptyObject({}); // true
isEmptyObject({foo:'bar'});  // false

hasOwnPropertyМетод вызова непосредственно на Object.prototypeтолько добавить немного больше безопасности , представьте себе следующее , используя обычный obj.hasOwnProperty(...)вызов:

isEmptyObject({hasOwnProperty:'boom'});  // false

Примечание: (на будущее) Приведенный выше метод опирается на for...inоператор, и этот оператор выполняет итерации только по перечисляемым свойствам. В наиболее широко применяемом на данный момент стандарте ECMAScript (3-е издание) у программиста нет никакого способа создания неперечислимых свойств. ,

Однако теперь это изменилось в ECMAScript 5th Edition , и мы можем создавать не перечисляемые, не записываемые или не удаляемые свойства, поэтому приведенный выше метод может завершиться ошибкой , например:

var obj = {};
Object.defineProperty(obj, 'test', { value: 'testVal', 
  enumerable: false,
  writable: true,
  configurable: true
});
isEmptyObject(obj); // true, wrong!!
obj.hasOwnProperty('test'); // true, the property exist!!

ECMAScript 5 решение этой проблемы будет:

function isEmptyObject(obj) {
  return Object.getOwnPropertyNames(obj).length === 0;
}

В Object.getOwnPropertyNamesметод возвращает Arrayсодержащий имена всех тех собственных свойств объекта, перечисляемого или нет , этот метод реализуется в настоящее время производителями браузеров, это уже на Chrome 5 Beta и последний WebKit ночные сборки.

Object.defineProperty также доступен в этих браузерах и последних версиях Firefox 3.7 Alpha.

CMS
источник
1
В чем преимущество Object.prototype.hasOwnProperty.call (obj, prop) перед obj.hasOwnProperty (prop)?
Кейси Чу
3
@Casey, отредактировано, если объект переопределяет hasOwnPropertyсвойство, функция может потерпеть крах ... Я знаю, что я немного параноик ... но иногда вы не знаете, в какой среде будет использоваться ваш код, но Вы знаете, какой метод вы хотите использовать ...
CMS
2
+1 за ответ на этот вопрос ... и другие вопросы будущего! :)
Даниэль Вассалло
1
Обратите внимание, что в IE также есть ошибка, когда, если у вас есть свойство с именем, совпадающим с не перечисляемым свойством Object.prototype, оно не будет перечислено for...in. Так isEmptyObject({toString:1})что не получится. Это одна из печальных причин вы не можете вполне использовать Objectкак отображение общего назначения.
bobince
1
@ MichaelMartin-Smucker - ключи возвращают только перечисляемые собственные свойства, поэтому здесь не подходят.
RobG
58

С jQuery вы можете использовать:

$.isEmptyObject(obj); // Returns: Boolean

Начиная с jQuery 1.4 этот метод проверяет как свойства самого объекта, так и свойства, унаследованные от прототипов (в том смысле, что он не использует hasOwnProperty).

С ECMAScript 5th Edition в современных браузерах (IE9 +, FF4 +, Chrome5 +, Opera12 +, Safari5 +) вы можете использовать встроенный метод Object.keys :

var obj = { blah: 1 };
var isEmpty = !Object.keys(obj).length;

Или просто старый JavaScript:

var isEmpty = function(obj) {
               for(var p in obj){
                  return false;
               }
               return true;
            };
kayz1
источник
33

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

var ad = {}; 
Object.keys(ad).length;//this will be 0 in this case

Поддержка браузеров: Firefox 4, Chrome 5, Internet Explorer 9, Opera 12, Safari 5

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

Zaptree
источник
13

Если вы используете underscore.js, вы можете использовать функцию _.isEmpty :

var obj = {};
var emptyObject = _.isEmpty(obj);
Грубый кролик
источник
1
Просто для тех, кто проходит мимо, это не метод, предназначенный для объектов. _.isEmpty([]) // true Обязательно проверьте сначала: stackoverflow.com/a/22482737/1922747
djv
11

Если вы хотите использовать lodash , вы можете использовать someметод.

_.some(obj) // returns true or false

Посмотрите этот маленький пример jsbin

SFS
источник
var x = [1,2] // true
djv 30.12.15
@damionjn Я добавил твой код в пример. Я вижу вашу точку зрения в том, что массив возвращает неправильный ответ, но OP первоначально объявил переменную как объект, так что я считаю, что это нормально. Выше приведен ответ, который использует метод подчеркивания isEmpty (у lodash тот же метод). Этот ответ имеет точно такую ​​же проблему. Если вы дадите isEmpty непустой массив, вы также получите неверный результат.
sfs
Справедливо, но мы должны предоставить ответы по всем основам, чтобы быть уверенными в лучших практиках. Вы правы, я прошел мимо его ответа без всякой критики. Просто для тех, кто проходит мимо, это не метод, предназначенный для объектов. _.some([1, 2]) // true Обязательно проверьте сначала: stackoverflow.com/a/13356338/1922747
djv
5
for (var hasProperties in ad) break;
if (hasProperties)
    ... // ad has properties

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

var hasProperties = false;
for (var x in ad) {
    if (ad.hasOwnProperty(x)) {
        hasProperties = true;
        break;
    }
}
if (hasProperties)
    ... // ad has properties
Кейси Чу
источник
1
в вашем решении нет фильтрации нежелательных свойств прототипа, это означает, что он может работать неправильно при использовании библиотеки, такой как Prototype.js, или неопытный пользователь добавил дополнительные свойства прототипа к объекту. Проверьте решение Daniels на этой странице.
Йоша
Вам не нужно использовать библиотеку или быть неопытным, чтобы расширить прототип объекта. Некоторые опытные программисты делают это постоянно.
Alsciende
2
for(var memberName in ad)
{
  //Member Name: memberName
  //Member Value: ad[memberName]
}

Член означает свойство члена, переменную члена, как вы хотите, чтобы она называлась> _>

Приведенный выше код вернет ВСЕ, включая toString ... Если вы только хотите увидеть, был ли расширен прототип объекта:

var dummyObj = {};  
for(var memberName in ad)
{
  if(typeof(dummyObj[memberName]) == typeof(ad[memberName])) continue; //note A
  //Member Name: memberName
  //Member Value: ad[memberName]

}

Примечание A: Мы проверяем, имеет ли член фиктивного объекта тот же тип, что и член нашего тестируемого объекта. Если это расширение, тип члена dummyobject должен быть "undefined"

бородавчатый
источник
Привет, я могу просто знать, содержит ли объект свойства или нет? Спасибо
Рики
в вашем решении нет фильтрации нежелательных свойств прототипа, это означает, что он может работать неправильно при использовании библиотеки, такой как Prototype.js, или неопытный пользователь добавил дополнительные свойства прототипа к объекту.
Йоша
Проверьте решение Daniels на этой странице - оно менее подвержено ошибкам!
Йоша
2
Ваш первый кодовый блок не покрывает это вообще. второй блок кода ведет себя неправильно, если я добавляю переменную к объекту "ad", которая не определена. Действительно, посмотрите ответ Дэниелса, он единственный правильный и быстрый, поскольку он использует собственную реализацию, называемую «hasOwnProperty».
Йоша
@Ricky: Если вы хотите проверить, содержит ли объект свойства, вы можете просто использовать пример в моем ответе: stackoverflow.com/questions/2673121/… . Если код достигает комментария, ваш объект не будет иметь никаких прямых свойств. Если нет, то будет.
Даниэль Вассалло
2
var hasAnyProps = false; for (var key in obj) { hasAnyProps = true; break; }
// as of this line hasAnyProps will show Boolean whether or not any iterable props exist

Простой, работает в любом браузере, и хотя технически это цикл для всех ключей объекта, он НЕ проходит через все их ... либо есть 0 и цикл не запускается, либо есть некоторые, и он прерывается после первого один (потому что все, что мы проверяем, если есть что-нибудь ... так зачем продолжать?)

Джимбо Джонни
источник
1

Ответ очень поздний, но это то, как вы можете справиться с прототипами.

Array.prototype.Any = function(func) {
    return this.some(func || function(x) { return x });
}

Object.prototype.IsAny = function() {
    return Object.keys(this).Any();
}
ProfiT
источник
0

Когда вы уверены, что объект является пользовательским, самым простым способом определить, является ли UDO пустым, будет следующий код:

isEmpty=
/*b.b Troy III p.a.e*/
function(x,p){for(p in x)return!1;return!0};

Хотя этот метод (по своей природе) дедуктивный, он самый быстрый и быстрый из возможных.

a={};
isEmpty(a) >> true

a.b=1
isEmpty(a) >> false 

ps:! не используйте его на объектах, определенных браузером.

Билл Ящерица
источник
... вернуть 0; возврат 1}; будет так же?
Commonpike
1
@pike no, return! 1; return! 0 - то же самое, что return false; вернуть true
Кристоф
0

Поздний ответ, но некоторые фреймворки обрабатывают объекты как перечислимые. Следовательно, bob.js может сделать это так:

var objToTest = {};
var propertyCount = bob.collections.extend(objToTest).count();
Тенгиз
источник
0

Вы можете использовать следующее:

Двойной взрыв! поиск недвижимости

var a = !![]; // true
var a = !!null; // false

hasOwnProperty Это то, что я использовал для:

var myObject = {
  name: 'John',
  address: null
};
if (myObject.hasOwnProperty('address')) { // true
  // do something if it exists.
}

Тем не менее, JavaScript решил не защищать имя метода, поэтому он может быть подделан.

var myObject = {
  hasOwnProperty: 'I will populate it myself!'
};

опора в myObject

var myObject = {
  name: 'John',
  address: null,
  developer: false
};
'developer' in myObject; // true, remember it's looking for exists, not value.

тип

if (typeof myObject.name !== 'undefined') {
  // do something
}

Однако, это не проверяет на ноль.

Я думаю, что это лучший способ.

в операторе

var myObject = {
  name: 'John',
  address: null
};

if('name' in myObject) {
  console.log("Name exists in myObject");
}else{
  console.log("Name does not exist in myObject");
}

результат:

Имя существует в myObject

Вот ссылка, которая более подробно описывает оператор in: Определение существования свойства объекта.

Джеймс Дринкард
источник
0

Функция ES6

/**
 * Returns true if an object is empty.
 * @param  {*} obj the object to test
 * @return {boolean} returns true if object is empty, otherwise returns false
 */
const pureObjectIsEmpty = obj => obj && obj.constructor === Object && Object.keys(obj).length === 0

Примеры:


let obj = "this is an object with String constructor"
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = {}
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = []
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = [{prop:"value"}]
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = {prop:"value"}
console.log(pureObjectIsEmpty(obj)) // empty? false
Себастьен
источник
-1

Как насчет этого?

var obj = {},
var isEmpty = !obj;
var hasContent = !!obj
Питер Тот
источник
Этот ответ не отвечает на вопрос. OP спрашивает, содержит ли объект определенные пользователем свойства - ваш ответ проверяет, преобразует ли сам объект логическое значение false.
жасмонат
... и позже я понял, что Джеймс уже включил эту опцию в свой ответ. Извините ребята.
Питер Тот