简单JavaScript OOP类

简单JavaScript OOP类,javascript,oop,Javascript,Oop,我使用的是John Resig的简单OOP类,它适用于使用“use strict”并取自 在所有示例中,我都看到了Class.extend的用法,如下所示: var MyObj = Class.extend({ init:function(){}, prop: "Property" }); 但是我发现以这种方式使用它有一个很大的缺点——我不能有“私有”变量,所以我不能像var$this=this那样存储对this的引用。 我为我的案例找到了解决方案,现在我使用类。通过以下方式扩

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

var MyObj = Class.extend({
    init:function(){},
    prop: "Property"
});
但是我发现以这种方式使用它有一个很大的缺点——我不能有“私有”变量,所以我不能像
var$this=this那样存储对
this
的引用。 我为我的案例找到了解决方案,现在我使用
类。通过以下方式扩展

var MyObj = Class.extend(new function(){
    var $this = this;
    this.init = function(){};
    this.prop = "Property";
});
在我的情况下,一切都正常,但我想知道,从长远来看,是否有一些事情会给我带来问题?
这样我的应用程序会在浏览器中消耗更多内存吗?
我有哪些替代方法来实现我的需求

注意:我需要存储$this,因为我大量使用事件和回调,所以我想引用“original”
这个
来轻松访问对象上的所有方法和属性

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

(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);
            });
        };
    });
} ());

您可以使用模块模式并维护所有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));
  • 工作示例
  • 如何使用继承和模块模式
我不能有“私有”变量

你当然可以。在(当前不必要的)
(函数(){…}())中包装器,或者在构造函数中(即
init
东西)

如果您确实需要您的代码像现在这样工作,请使用

(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
数组。而且您在上没有使用任何实例方法(仅在类上使用构造函数和静态元素),因此类模式似乎没有必要。改用。如果需要单个实例(和类),代码应如下所示:

"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);
    }
});

哎哟,不。我简直不敢相信这真的对你有用。请向我们展示您如何将此“类”用于事件和回调;可能会发布您的实际代码(至少是涉及
$this
)的方法。@Bergi我添加了示例-这确实有效,代码已经通过了QA阶段:)在任何对象内部,您应该能够访问当前对象的
this
。@travis如果您看到,在jQuery文档就绪时,我使用的是$this,因为如果我使用它,它将不会引用QuickPlay:)的实例,然后激发QA团队:-/若要看到它崩溃,您可以尝试创建多个实例。还是应该是单身?那么你就不应该使用
类了。它看起来不错,但是继承呢?在您的模式中,我如何创建继承自YourModule名称的MySecondModule?类为我提供了它。我添加了引用来解释它是如何工作的。很高兴提供帮助:)谢谢,我看到了链接…我相信它会起作用,但对其他团队成员来说太复杂了:(我正在尝试一些简单易用的东西……在我的公司,我们使用这种模式,维护组织,防止将来出现一些问题。为什么不花点时间学习更复杂的模式呢?将来,也许你在组织上有问题,必须重构你所有的代码。想想看:)我发誓,这并没有那么复杂;)@RafaelGomes:你所拥有的看起来不像是一个(单例)模块,更像是一个类。您不会使它成为可实例化的,而是在IEFE中创建它。并删除
new
关键字,您只是从工厂返回一个对象,而不是调用构造函数!感谢您以我使用类的方式向我指出这个“巨大”的问题……在我的应用程序中,我需要使用“单例”和类来解决,所以看起来我需要为每种情况使用/创建两种不同的模式。目前,我刚开始在项目中使用JS OOP,所以现在改变还不算晚:)你能告诉我一个好的模式,如何创建一个需要在创建时用数据初始化的“模块”吗?我认为单例模块是静态的,没有“创建”。我可以想到a)数据被编码到模块代码b)模块本身从全局“数据存储”获取数据c)全局控制器通过调用
init
方法以数据作为参数来“启动”模块。有关代码结构模式,请参阅我链接的Osmani文章。
"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);
    }
});