Knockout Observable CSS Class Binding

HTML

<div data-bind="class: single">Single Observable Class</div>
<div data-bind="class: multiple">Multiple Observable Classes</div>
<button data-bind="click: change">Change</button>

<pre data-bind="text: ko.toJSON($root)"></pre>

CSS

.red {
    background: red;
}
.black {
    background: black;
}
.blue {
    background: blue;
}
.small {
    font-size: 12px;
}
.big {
    font-size: 20px;
}

JavaScript

//
// Observable CSS Class Binding
//
// See Fiddle for usage: http://jsfiddle.net/kamranayub/3ahUA/
//
ko.bindingHandlers['class'] = {
    update: function (element, valueAccessor) {
        var currentValue = ko.utils.unwrapObservable(valueAccessor()),
            prevValue = element['__ko__previousClassValue__'],
            
            // Handles updating adding/removing classes
            addOrRemoveClasses = function (singleValueOrArray, shouldHaveClass) {
                if (Object.prototype.toString.call(singleValueOrArray) === '[object Array]') 									{          
                    ko.utils.arrayForEach(singleValueOrArray, function (cssClass) {
                      var value = ko.utils.unwrapObservable(cssClass);
                      ko.utils.toggleDomNodeCssClass(element, value, shouldHaveClass);
                    });
                } else if (singleValueOrArray) {
                    ko.utils.toggleDomNodeCssClass(element, singleValueOrArray, shouldHaveClass);
                }
            };
        
        // Remove old value(s) (preserves any existing CSS classes)
        addOrRemoveClasses(prevValue, false);
        
        // Set new value(s)
        addOrRemoveClasses(currentValue, true);
        
        // Store a copy of the current value
        element['__ko__previousClassValue__'] = currentValue.concat();
    }
};

//
// Tests
//
var vm = {
    single: ko.observable("red"),
    multiple: ko.observableArray(["blue","small"])
};
vm.change = function () {
    vm.single(vm.single() === "red" ? "black" : "red");
    
    if (vm.multiple.indexOf("small") > -1) {
        vm.multiple.remove("small");
        vm.multiple.push("big");
    } else {
        vm.multiple.remove("big");
        vm.multiple.push("small");
    }    
};

ko.applyBindings(vm);