1

How do you set up an Object that has multiple functions the second code example is what I'm trying todo

Object.defineProperty(NodeList.prototype, 'each', {
    value: function (fn) {
        return Array.from(this).forEach((node, index) => fn(node, index))
    }
});

// below doesn't work

HTMLElement.prototype = {
   hasClass: function(selector) {
   },
   next: function(selector) {
   }
}
ONYX
  • 5,679
  • 15
  • 83
  • 146

1 Answers1

2

Use Object.assign instead:

Object.assign(HTMLElement.prototype, {
  hasClass(selector) {
    return this.classList.contains(selector);
  },
  next(selector) {
    const { nextElementSibling } = this;
    return nextElementSibling && nextElementSibling.matches(selector)
    ? nextElementSibling
    : null;
  }
});

const div = document.querySelector('div');
console.log(div.hasClass('foo'));
console.log(div.next('div'));
<div class="foo"></div>

(that said, note that mutating the built-in prototypes is not very good practice, and can result in problems, especially when you start including other scripts on your page - better to define standalone functions, or to make your own wrapper around elements that has such methods)

You could also use Object.defineProperties to define multiple properties at once, but the code required is more long-winded.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • When you say mutating built-in prototype is not good practice and can result in problems like including other scripts what kind of problems do you mean. I'm building my own javascript library based of HTMLElement - what would you do – ONYX Apr 15 '19 at 02:19
  • See https://stackoverflow.com/questions/14034180/why-is-extending-native-objects-a-bad-practice . If you're making a library, consider using a wrapper around the elements instead, like I suggested - then, calling your custom functions on wrapped elements will work, without having to change the built-in behavior. – CertainPerformance Apr 15 '19 at 02:21
  • Can you make me an example of what a wrapper is when making a library – ONYX Apr 15 '19 at 02:23
  • For example, remember how we had to back out of the `Array.prototype.flatten` proposal because a *very few* old websites using MooTools had added their own custom `Array.prototype.flatten` methods to the prototype, thereby breaking their sites? As a result we got sillyness like [this](https://github.com/staltz/prevent-smoosh). Best to avoid causing problems like that, by not mutating built-in prototypes – CertainPerformance Apr 15 '19 at 02:25
  • You can make a class which you can call with an HTMLElement. Then just put methods on the class, instead of on HTMLElement.prototype. – CertainPerformance Apr 15 '19 at 02:26