简单的JavaScript OOP类

时间:2013-07-25 20:30:19

标签: javascript oop

我正在使用John Resig的简单OOP Class,它适用于使用“use strict”并取自SO post
在所有示例中,我都看到Class.extend的用法如下:

var MyObj = Class.extend({
    init:function(){},
    prop: "Property"
});

但是我发现以这种方式使用它有很大的缺点 - 我不能拥有“私有”变量,因此我无法将this的引用存储为var $this = this;。 我为我的案例找到了解决方案,现在我按照以下方式使用Class.extend

var MyObj = Class.extend(new function(){
    var $this = this;
    this.init = function(){};
    this.prop = "Property";
});

一切都适用于我的情况,但我想知道是否有一些事情可能会导致长期问题?
这样我的应用程序会在浏览器中消耗更多内存吗? 我有哪些替代方法来实现我的需求?

注意:我需要存储$ this,因为我使用了大量事件和回调,因此我想引用“原始”this,以便轻松访问所有方法和属性对象

编辑:根据要求,这是我的代码示例:

(function () {
    "use strict";
    window.QuickPlay = Class.extend(new function () {
        var $this = this;

        this.init = function (initData) {
            $this.elementsToHide.push(initData.el);
            $(function () {
                playProcessStart();
                Sys.Application.add_load(function () {
                    $find("ctl00_ContentPlaceHolderMain_ctrlPlayPopup1").add_closed(function () { $this.setElementsVisibility(""); });
                });
                $this.setElementsVisibility("hidden");
            });
        };

        this.elementsToHide = [];

        this.setElementsVisibility = function (visibility) {
            $.each($this.elementsToHide, function (i) {
                $("#" + this).css("visibility", visibility);
            });
        };
    });
} ());

2 个答案:

答案 0 :(得分:2)

您可以使用模块模式并维护所有OOP。这种模式为您的代码提供了更高的安全性和更好的组织。

//these are namespaces in javascript
window.project = window.project || {}; //this kind declarations prevents recreate the object
project.group = project.group || {};

//in the line below we can use $ instead jQuery, and use window and document instead ask for the browser every time.
(function (window, document, $) {
    "use strict";

    project.group.NameOfYourModule = function () {
        var privateAttribute = true,
            students = 32,    //It's is a best practice declare everything in an unique var.

            privateMethod = function () {
                alert('Now I know OOP using jQuery');
            };

        return {
            init: function () {
                //this is a public method and we can initiate some private method;
                privateMethod();

                //we call a public method using this
                this.publicMethod();
            },
            publicMethod: function () {
                //this is a public method
            }
        };
    };

    $(function () {
        var myclass = new project.group.NameOfYourModule(); //instantiate you class
        myclass.init(); //initiate some public method
    });
}(window, document, jQuery));
  • JsFiddle
  • 的工作示例
  • 如何使用继承和模块模式here

答案 1 :(得分:1)

  

我不能拥有“私人”变量

当然可以。在(当前不必要的)(function () { … } ());包装器中,或在构造函数中(init)。

new function () {

Avoid that pattern!如果你真的需要你的代码像现在一样工作,请使用

(function () {
    "use strict";
    // Here's the place where you could put a private, static variable
    // for example `var elementsToHide = [];`
    var $this = {
        init: function (initData) {
            $this.elementsToHide.push(initData.el);
            $(function () {
                playProcessStart();
                Sys.Application.add_load(function () {
                    $find("ctl00_ContentPlaceHolderMain_ctrlPlayPopup1").add_closed(function () {
                        $this.setElementsVisibility("");
                    });
                });
                $this.setElementsVisibility("hidden");
            });
        },
        elementsToHide: [],
        setElementsVisibility: function (visibility) {
            $.each($this.elementsToHide, function (i) {
                $("#" + this).css("visibility", visibility);
            });
        }
    };
    window.QuickPlay = Class.extend($this);
}());
  

我想知道是否有一些可能导致我出现问题的事情

是。多个实例几乎不起作用,因为它们都引用相同的elementsToHide数组。而且你没有使用任何实例方法(只有你的类上的构造函数和静态元素),所以类模式似乎是不必要的。请改用a module。如果您需要单个实例(和类),代码应如下所示:

"use strict";

window.QuickPlay = Class.extend({
    init: function (initData) {
        var $this = this;
        this.elementsToHide = [];
        $(function () {
            playProcessStart();
            $this.elementsToHide.push(document.getElementById(initData.el));
            Sys.Application.add_load(function () {
                $find("ctl00_ContentPlaceHolderMain_ctrlPlayPopup1").add_closed(function () {
                    $this.setElementsVisibility("");
                });
            });
            $this.setElementsVisibility("hidden");
        });
    },
    setElementsVisibility: function (visibility) {
        $(this.elementsToHide).css("visibility", visibility);
    }
});