{"id":4641,"date":"2012-08-18T09:32:08","date_gmt":"2012-08-18T13:32:08","guid":{"rendered":"http:\/\/www.ericfeminella.com\/blog\/?p=4641"},"modified":"2016-03-30T14:06:12","modified_gmt":"2016-03-30T18:06:12","slug":"determining-if-an-object-is-empty-with-underscore-lo-dash","status":"publish","type":"post","link":"https:\/\/www.ericfeminella.com\/blog\/2012\/08\/18\/determining-if-an-object-is-empty-with-underscore-lo-dash\/","title":{"rendered":"Determining if an object is empty with Underscore \/ Lo-dash"},"content":{"rendered":"<p>When leveraging the utilities provided by <a href=\"http:\/\/underscorejs.org\/\" target=\"_blank\">Underscore<\/a> or <a href=\"http:\/\/lodash.com\/\" target=\"_blank\">Lo-dash<\/a>, determining if an Array, String or Object is empty is quite simple via the <a href=\"http:\/\/underscorejs.org\/#isEmpty\" target=\"_blank\">isEmpty()<\/a> method. <\/p>\n<h2>The isEmpty() method and Objects<\/h2>\n<p>In the context of an Object, it is important to keep in mind that <code>_.isEmpty()<\/code> is implemented such that it determines an Object as being empty in a literal sense. That is, objects are traversed to determine the existence of any <a href=\"https:\/\/developer.mozilla.org\/en\/JavaScript\/Reference\/Global_Objects\/Object\/HasOwnProperty\" target=\"_blank\">own<\/a> properties &#8211; irrespective of their actual values. Thus, <code>_.isEmpty()<\/code> will return false if an object contains <em>any<\/em> own properties, even if all property values are undefined, otherwise it will return true. <\/p>\n<p>While these details may seem obvious, it is important to be mindful of them in order to avoid potential false positives when trying to determine if an object&#8217;s properties are all undefined. <\/p>\n<p>For example, consider the following object: <\/p>\n<pre class=\"lang:js decode:true\">\r\nvar obj = {\r\n  'firstName': undefined\r\n, 'lastName' : undefined\r\n};\r\n<\/pre>\n<p>Technically, the above object is not empty, as it contains two <em>own<\/em> properties. Thus, invoking <code>_.isEmpty()<\/code> with this object will return false, which is correct, though one may have mistakenly assumed it to have returned true since all of the object&#8217;s properties are undefined.<\/p>\n<pre class=\"lang:js decode:true\">\r\nvar obj = {\r\n  'firstName': undefined\r\n, 'lastName' : undefined\r\n};\r\n_.isEmpty(obj); \/\/ false\r\n<\/pre>\n<h2>Extending Underscore \/ Lo-dash<\/h2>\n<p>With an understanding in mind of how <code>_.isEmpty()<\/code> is implemented in the context of objects, should one need to determine if an object is empty based on the values of it&#8217;s <code>own<\/code> properties being undefined, a simple extension, such as the following, can be <a href=\"http:\/\/documentcloud.github.com\/underscore\/#mixin\" target=\"_blank\">mixed into Underscore<\/a> or <a href=\"http:\/\/lodash.com\/docs#mixin\" target=\"_blank\">Lo-dash<\/a> to provide both the default implementation as well as an extended implementation which takes this into account:<\/p>\n<pre class=\"lang:js decode:true\">\r\n\/*\r\n * Provides a convenience extension to _.isEmpty which allows for\r\n * determining an object as being empty based on either the default\r\n * implementation or by evaluating each property to undefined, in\r\n * which case the object is considered empty.\r\n *\/\r\n_.mixin( function() {\r\n  \/\/ reference the original implementation\r\n  var _isEmpty = _.isEmpty; \r\n  return {\r\n    \/\/ If defined is true, and value is an object, object is considered \r\n    \/\/ to be empty if all properties are undefined, otherwise the default \r\n    \/\/ implementation is invoked.\r\n    isEmpty: function(value, defined) {\r\n      if (defined && _.isObject(value)) {\r\n        return !_.any( value, function(value, key) {\r\n          return value !== undefined;\r\n        });\r\n      } \r\n      return _isEmpty(value);\r\n    }\r\n }\r\n}());\r\n<\/pre>\n<p>Given the above, we can then invoke the original <code>isEmpty<\/code> implementation, as well as the extended implementation as follows:<\/p>\n<pre class=\"lang:js decode:true\">\r\nvar obj = {\r\n  'firstName': undefined\r\n, 'lastName' : undefined\r\n};\r\n\/\/ invoke the original implementation\r\n_.isEmpty(obj); \/\/ false\r\n\r\n\/\/ invoke the extended implementation, by passing true\r\n_.isEmpty(obj, true); \/\/ true\r\n<\/pre>\n<p>The ease with which libraries such as Underscore and Lo-dash allow for adding extensions and overriding default implementations is a key design feature which makes them not only extremely flexible, but also quite enjoyable to work with as well.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When leveraging the utilities provided by Underscore or Lo-dash, determining if an Array, String or Object is empty is quite simple via the isEmpty() method. The isEmpty() method and Objects In the context of an Object, it is important to keep in mind that _.isEmpty() is implemented such that it determines an Object as being empty in a literal sense&#8230;. <a class=\"read-more\" href=\"https:\/\/www.ericfeminella.com\/blog\/2012\/08\/18\/determining-if-an-object-is-empty-with-underscore-lo-dash\/\">Continue Reading<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[44,78],"tags":[198,197,196,202],"class_list":["post-4641","post","type-post","status-publish","format-standard","hentry","category-code-review","category-javascript-2","tag-hasownproperty","tag-lo-dash","tag-underscore","tag-_-isempty"],"jetpack_publicize_connections":[],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/posts\/4641","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/comments?post=4641"}],"version-history":[{"count":0,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/posts\/4641\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/media?parent=4641"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/categories?post=4641"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ericfeminella.com\/blog\/wp-json\/wp\/v2\/tags?post=4641"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}