Bilal075_ Bilal075_ - 3 months ago 8
Javascript Question

JavaScript - adding prototype(s) to a specific object

So i've been stuck for a couple of days trying to figure out the best practice of implementing the following function into my project:

function addClass(myElem, myClass)
{
if (typeof myElem != "undefined" && myElem && myElem.nodeType === 1 && myClass)
{
myClass = (typeof myClass == "string" ? myClass.trim().replace(/[\s]{2,}/g, ' ').split(", ").join(",").split(",").join(" ").split(" ") : myClass);

for (var i = 0; i < myClass.length; i++)
{
myClass[i] = myClass[i].trim();
if (myClass[i].length > 0 && hasClass(myElem, [myClass[i]], true) === false)
{
myElem.className += " " + myClass[i];
}
}

return true;
}

return false;
}


This function basically has the same behavior as jQuerys $.addClass prototype / function, but has (at the moment) no support for inline calling (like the inbuilt functions: .trim(), .toLowerCase(), etc etc).

I've read that extending / adding prototypes to an object, isn't really considered good practice and must be avoided if you care about performance (which I do). But as you noticed.. my knowledge about prototypes isn't that great, so any suggestions / answers are more then welcome!

In Short:
Basically I want to implement this function, and be callable like this: document.body.addClass("classToBeAdded");

Answer

I've read that extending / adding prototypes to an object, isn't really considered good practice

It's a matter of opinion, but it does raise the likelihood of conflicts (e.g., two different scripts both adding the same method to a prototype).

and must be avoided if you care about performance (which I do).

No, adding things to a prototype object doesn't have any significant performance impact; replacing the prototype of an object once the object is created does, but you don't need to do that.

Basically I want to implement this function, and be callable like this: document.body.addClass("classToBeAdded");

You can add it to HTMLElement.prototype:

Object.defineProperty(HTMLElement.prototype, "addClass", {
    value: function() {
        // ...your code here...
    }
});

That works on all modern browsers, and also IE8.

Example:

// The extension
Object.defineProperty(HTMLElement.prototype, "addClass", {
  value: function(cls) {
    // Not using classList on the assumption that addClass would be unnecessary
    // if the browser supported classList :-)
    this.className += " " + cls;
  }
});

// Using it
document.body.addClass("foo");
document.getElementById("test").addClass("bar");
.foo {
  color: green;
  font-weight: bold;
}
.bar {
  border: 1px solid blue;
}
<p id="test">This is a test</p>