5
\$\begingroup\$

I needed this small function for one of my project.

Fetch Attributes

function fetchAttrs(node) {

  if (!node || !node.hasAttributes()) return {};
  var attrs = node.attributes;
  var res = {};
  var length = attrs.length;
  for (var i = 0; i < length; i++) {
    var attr = attrs[i];
    res[attr.name] = attr.value;
  }
  return res;
}

It's working fine as expected but I wanted to know if I am missing something from a performance point of view or good coding practices. Just need a second opinion :)

Update

How to handle exceptions, is it a good practice?

\$\endgroup\$
1
  • 1
    \$\begingroup\$ From a safety point of view, you are assuming the passed in node has both .hasAttributes() and .attributes or it will throw an exception. \$\endgroup\$
    – jfriend00
    Oct 20, 2014 at 6:13

1 Answer 1

4
\$\begingroup\$

There's not much of a performance difference between the two (reduce is very slightly favoured in my own tests), but I prefer the more readable reduce function over the for loop. I believe it makes the code simpler, too. Also sort of a personal preference - why not use the full name? No real need in shortening it. :-)

var fetchAttributes = function(node) {
  return node && Array.prototype.reduce.call(node.attributes, function(list, attribute) {
    list[attribute.name] = attribute.value;
    return list;
  }, {}) || {};
};

http://jsperf.com/reduce-vs-for-fetch-attributes

Edit: In fact you can simplify this further, as you aren't transforming the attributes in any way.

var fetchAttributes = function(node) {
    return node && node.attributes || {};
};
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Johan, node.attributes is an object, not an array; so we have to borrow the reduce method from the array prototype. If it were, you could simply do return node && node.attributes.reduce(function(list, attribute) { // ... . :-) \$\endgroup\$
    – Ben
    Oct 20, 2014 at 22:01
  • \$\begingroup\$ Seems a elegant approach. But I have a doubt in mind, reduce will be called for each element and hence will be a overhead as compared to simple attribute access. \$\endgroup\$
    – vivek
    Oct 21, 2014 at 2:09
  • \$\begingroup\$ Does it really work? jsfiddle.net/55gx9q47 \$\endgroup\$
    – Johan
    Oct 21, 2014 at 7:56
  • \$\begingroup\$ Doesn't seem to with a plain object. However the callback function is called when iterating over the node.attributes object. See my updated answer for a solution without using reduce at all. \$\endgroup\$
    – Ben
    Oct 21, 2014 at 9:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.