The Decorator pattern is a structural design pattern that attaches additional responsibilities to an object dynamically promoting code reusability and is a flexible alternative to subclassing.

The decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows the behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. - Wikipedia.

The Decorator pattern adds new behavior to objects dynamically at runtime wrapping itself around the original object. Multiple decorators can add or override functionality to the original object.

While this pattern provides flexibility to statically typed languages, like Java and C#, by allowing runtime changes as opposed to inheritance which takes place at compile time, JavaScript is a dynamic language, and the ability to extend an object at runtime is baked into the language itself.


I am going to borrow a great example from Addy Osmani's post about the subject.

//What we're going to decorate
function MacBook() {
    this.cost = function () { return 997; };
    this.screenSize = function () { return 13.3; };
/*Decorator 1*/
function Memory(macbook) {
    var v = macbook.cost();
    macbook.cost = function() {
        return v + 75;
 /*Decorator 2*/
function Engraving( macbook ){
   var v = macbook.cost();
   macbook.cost = function(){
     return  v + 200;

/*Decorator 3*/
function Insurance( macbook ){
   var v = macbook.cost();
   macbook.cost = function(){
     return  v + 250;
var mb = new MacBook();
console.log(mb.cost()); //1522
console.log(mb.screenSize()); //13.3

Here, the decorators are overriding the superclass .cost() method to return the current price of the MacBook plus with the cost of the upgrade being specified. It's considered a decoration as the original Macbook object's constructor methods which are not overridden (e.g. screenSize()) as well as any other properties which we may define as a part of the Macbook remain unchanged and intact.

As you can probably tell, there isn't a defined interface in the above example, and duck typing is used to shift the responsibility of ensuring an object meets an interface when moving from the creator to the receiver.