3

我正在使用 John Resig 的简单 OOP Class,它适用于“使用严格”并取自SO post
在所有示例中,我都看到了Class.extend这样的用法:

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

但是我发现以这种方式使用它对我来说有一个很大的缺点——我不能有“私有”变量,所以我不能存储对thislike的引用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);
            });
        };
    });
} ());
4

2 回答 2

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));
于 2013-07-25T20:43:40.810 回答
1

我不能有“私人”变量

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

new function () {

避免这种模式!如果您真的需要您的代码像现在一样工作,请使用

(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);
    }
});
于 2013-07-25T21:14:04.343 回答