I know this is a lot of code, but I'm not looking for any kind of detailed review of the code.  I'm just hoping some nice Javascript guru can give it a once over and offer any needed advice for using OOP in Javascript better than I am. Here are a few areas of concern that I have, that don't quite seem like they're ideal.The page has 4 objects that interact with each other, just floatingin the middle of nowhere.The objects are all created by invoking anonymous constructors, since I didn't want named functions that are only used once hanging around.Most of the constructors have as the first line var me = this; since this changes context.There are about 4 or 5 global fields and functions that didn't really fit into any objects, so I just left them hanging in the global context.Any pointers on utilizing object oriented programming in JavaScript would be much appreciated.    var mode = dev;    var currentSrc = [];    var initialTitleValue =    [Title]              ;    var initialSelectedSubject = { id: -1, txt: Books' Subjects };    var currentDisplay = ;    $(function () {        $(#header h1).text(Knockout / jQuery Book Demo);        $(#tbTitleSearch).blur(function () {            if (!$(this).val().trim()) {                viewModel.titleValue(initialTitleValue);                $(this).addClass(watermark);            }        });        $(#tbTitleSearch).click(function () {            if ($(this).val() == initialTitleValue) {                viewModel.titleValue();                $(this).removeClass(watermark);            }        });        $(#tbGenreSearch).click(function () {            if (viewModel.selectedSubjects().length == 1 && viewModel.selectedSubjects()[0] == initialSelectedSubject) {                $(this).removeClass(watermark);                viewModel.selectedSubjects.removeAll();            }            openSubjectWindow();        });        viewModel.selectedSubjects.subscribe(function () {            if (viewModel.selectedSubjects().length == 1 && viewModel.selectedSubjects()[0] == initialSelectedSubject)                $(#tbGenreSearch).addClass(watermark);        });        $(window).bind('resize', function () {            gridManager.sizeGrid();        }).trigger('resize');        $(.bookItem).live(mouseover, function () { $(this).addClass(highlight); });        $(.bookItem).live(mouseout, function () { $(this).removeClass(highlight); });        $(.smCovTempl).live(mouseover, function () { $(this).addClass(highlight); });        $(.smCovTempl).live(mouseout, function () { $(this).removeClass(highlight); });        $(.bookItem).live(click, function () { $(this).toggleClass(selected); });        $(.smCovTempl > img).live(click, function () { bookDetailsPopup($(this).data(id)); });        theme(grid);        ko.applyBindings(viewModel);        dataLoader.loadSubjects();    });    var viewModel = new (function () {        var me = this;        this.rows = ko.observableArray([]);        this.currentTemplate = ko.observable(bookTemplate1);        this.displayTemplate = function () { return me.currentTemplate(); };        this.subjects = ko.observableArray([]);        this.selectedSubjects = ko.observableArray([initialSelectedSubject]);        this.selectedSubjectNames = function () { return $(me.selectedSubjects()).map(function (i, o) { return o.txt; }).get(); };        this.selectedSubjectIds = function () { return $(me.selectedSubjects()).map(function (i, o) { return o.id; }).get(); };        this.manageSingleSelectedSubject = function () {            if (me.selectedSubjects().length == 0)                me.selectedSubjects.push(initialSelectedSubject);        };        this.readStatus = ko.observable(-1);        this.includeChildSubjects = ko.observable(true);        this.titleValue = ko.observable(initialTitleValue);        this.animateOnEntry = true;        this.templateItemRendered = function (element) {            if (me.animateOnEntry)                $(element).fadeIn();        };    })();    var dataLoader = new (function () {        var me = this;        this.loadAllBooks = function () {            dataManager.clearCurrentData();            if (mode == 'dev')                me.loadTestData();            else                post(../PublicServices/KnockoutService.asmx/ReadAll, '{}',                    function (d) {                        currentSrc = d.d;                        dataManager.refreshCurrentData();                    });        };        this.searchForBooks = function () {            alert(viewModel.titleValue());        };        this.loadSubjects = function () {            viewModel.subjects([{ name: Sub1, id: 1, children: [] },                { name: Sub2, id: 2, children: [{ name: Sub2a, id: 4, children: [{ name: Sub2a1, id: 6, children: []}] }, { name: Sub2b, id: 5, children: []}] },                { name: Sub3, id: 3, children: []}]);            $(#jsTreeTarget).jstree({                themes: {                    theme: default,                    dots: false,                    icons: false                },                checkbox: { two_state: true },                plugins: [themes, html_data, checkbox, ui]            });            $(#jsTreeTarget).bind(change_state.jstree, function () {                viewModel.selectedSubjects(                    $(li.jstree-checked > a, #jsTreeTarget).map(function (i, o) { return { txt: $(o).text(), id: $(o).data(id) }; }).get());            });        };        this.loadTestData = function () {            currentSrc = [{ id: 1, title: Mr. Jefferson's Hammer.  William Henry Harrison and the foundation of Indian Policy, authors: [a1, a2], subjects: [sub1, sub2], smImg: 1, medImg: 1, pub: Oxford, pubYear: 2004, pages: 250, asin: a, isRead: false },                { id: 1, title: Founding Brothers, authors: [a1, a2], subjects: [sub1, sub2], smImg: 1, medImg: 1, pub: Oxford, pubYear: 2004, pages: 250, asin: a, isRead: false },                { id: 1, title: American Creation, authors: [a1, a2], subjects: [sub1, sub2], smImg: 1, medImg: 1, pub: Oxford, pubYear: 2004, pages: 250, asin: a, isRead: false}];            for (var i = 0; i < 50; i++)                currentSrc.push({ id: 1, title: American Creation, authors: [a1, a2], subjects: [sub1, sub2], smImg: 1, medImg: 1, pub: Oxford, pubYear: 2004, pages: 250, asin: a, isRead: false });            dataManager.refreshCurrentData();        };    })();    var dataManager = new (function () {        var me = this;        this.templateDataNotLoaded = false;        this.refreshCurrentData = function () {            if (currentDisplay == grid)                gridManager.reloadGrid();            else {                me.templateDataNotLoaded = false;                me.cascadeData();            }        };        this.cascadeData = function (index) {            me.animateOnEntry = true;            if (!index)                index = 0;            if (index == currentSrc.length - 1)                return;            if (index >= 30) {                viewModel.animateOnEntry = false;                for (var i = index; i < currentSrc.length; i++)                    viewModel.rows.push(currentSrc[i]);            } else {                viewModel.rows.push(currentSrc[index]);                setTimeout(function () { me.cascadeData(index + 1); }, 60);            }        };        this.dumpDataWithoutCascade = function () {            me.templateDataNotLoaded = false;            viewModel.rows(currentSrc);        };        this.clearCurrentData = function () {            currentSrc.length = 0;            viewModel.rows.removeAll();            gridManager.unloadGrid();            me.templateDataNotLoaded = true;        };    })();    var gridManager = new (function () {        var me = this;        this.gridDataNotLoaded = false;        this.reloadGrid = function () {            me.gridDataNotLoaded = false;            $(#jqGridElement).jqGrid({                datastr: { rows: currentSrc },                jsonReader: { repeatitems: false },                datatype: jsonstring,                colNames: ['', 'Title', 'Pages', 'Publisher', 'Authors', Subjects],                colModel: [                    { name: 'smImg', index: 'smImg', width: 65, fixed: true, sortable: false, formatter: gridCoverFormatter, title: false },                    { name: 'title', width: 250, formatter: titleFormatter, title: false },                    { name: 'pages', width: 80, fixed: true, align: 'center', title: false },                    { name: 'pub', index: 'pub', width: 100, formatter: publisherFormatter, title: false },                    { name: 'authors', width: 100, formatter: authorFormatter, sortable: false, title: false },                    { name: 'subjects', width: 100, formatter: subjectFormatter, sortable: false, title: false}],                height: 'auto',                gridview: true,                rowNum: -1            });            me.sizeGrid();        };        this.unloadGrid = function () {            me.gridDataNotLoaded = true;            $(#jqGridElement).jqGrid('GridUnload');        };        this.sizeGrid = function () {            var targetContainer = #contentParent;            var gridID = #jqGridElement;            var width = $(targetContainer).width();            var height = $(targetContainer).height();            width = width - 20; // Fudge factor to prevent horizontal scrollbars            height = height - 40;            if (width > 0) //&& Math.abs(width - $(gridID).width()) > 5) {                $(gridID).jqGrid('setGridWidth', width);            if (height > 0) // && Math.abs(height - jQuery(gridID).height()) > 5)                $(gridID).jqGrid('setGridHeight', height);        };        function gridCoverFormatter(cellvalue, options, rowObject) {            return <div style='height:85px;'><img src='../Books/Covers/Small/ + cellvalue + .jpg' style='margin-top:5px;' /></div>;        }        function titleFormatter(cellvalue, options, rowObject) {            return <div title=' + cellvalue.toString().replace(', ) + '> + cellvalue + </div><a href='http://www.google.com?a= + rowObject.asin + ' target='_blank'><img src='../Img/Misc/Amazon.png'</a>;        }        function publisherFormatter(cellvalue, options, rowObject) {            var formattedVal = cellvalue.toString().replace(', );            if ((formattedVal != ) && (rowObject.pubYear))                formattedVal +=  -  + rowObject.pubYear;            return <div title=' + formattedVal + '> + formattedVal + </div>;        }        function authorFormatter(cellvalue, options, rowObject) {            var result = ;            for (var i = 0; i < cellvalue.length; i++)                result += <li><span> + cellvalue[i] + </span></li>;            return <ul class='grAUL'> + result + </ul>;        }        function subjectFormatter(cellvalue, options, rowObject) {            var result = ;            for (var i = 0; i < cellvalue.length; i++)                result += <li title=' + cellvalue[i] + '> + Oxford - 2004 + </li>;            return <ul class='grSUL'> + result + </ul>;        }    })();    function theme(value) {        if (value == grid) {            manageDisplay(#gridParent, #templateElement, 'emptyBookTemplate');            if (gridManager.gridDataNotLoaded)                gridManager.reloadGrid();        } else {            manageDisplay(#templateElement, #gridParent, value);            if (dataManager.templateDataNotLoaded)                dataManager.dumpDataWithoutCascade();        }        currentDisplay = value;    }    function manageDisplay(showID, hideID, newTemplate) {        $(showID).show();        $(hideID).hide();        viewModel.currentTemplate(newTemplate);    }    function bookDetailsPopup(id) {        var divToPopup = $(#bookInfoPopup).clone();        $(divToPopup).dialog({ width: 400, height: 400 });        $.get(PartialBookInfo.aspx?id= + id, function (response) {            $(.popupContent, divToPopup).html(response);            $(.tabDiv, divToPopup).tabs();            $(.loadingMsg, divToPopup).remove();        });    }    function openSubjectWindow() {        $(#treeWrapper).dialog({            title: Header,            close: function () { viewModel.manageSingleSelectedSubject(); }        });    }    function post(targetURL, dataInput, success) {        $.ajax({            url: targetURL,            type: POST,            contentType: application/json; charset=utf-8,            data: dataInput,            dataType: json,            success: success,            async: true        });    }
Book catalog demo using Knockout, jQuery, and JSON
javascript;jquery;object oriented;json;knockout.js