更好的设计,以便从对象的方法引用自己的对象的属性

时间:2012-07-11 16:46:17

标签: javascript oop

我有一个'yesno'输入收音机。当用户点击时,会显示yesDiv,当用户点击 no 时,会显示noDiv。

为了实现我创建了对象 myObject

var myObject= {
        init: function(config){
            this.config=config;
            this.config.InputRadio.bind('click',this.config,this.switchDiv);
        },
        switchDiv: function(ev){
                    self=ev.data;
            if ($(this).val()==1){
                self.divYes.hide();
                self.divNo.show();
            }else{
                self.divYes.show();
                self.divNo.hide();
            }
        }
}

myObject.init({
        InputRadio:$("input[name=yesno]"),
        divYes:$("#yesDiv"),
        divNo:$("#noDiv")
});

这很有效,我知道我不能使用 this 来引用方法'switchDiv'中的对象属性,因为函数内部有'this'的范围。我找到了将 this.config 作为参数发送的解决方案,然后在相关问题(Referencing own object properties中使用 self = ev.data 。)

但现在我的问题是:每当我想从该对象的方法访问对象自己的属性时,我必须将它们作为方法中的参数传递,这一点并不奇怪吗?是否有更好的方法来声明对象以避免这种情况?

3 个答案:

答案 0 :(得分:2)

如果您想在致电this时确保myObject引用switchDiv,我的建议是稍微更改您的init功能。我还更新了您的switchDiv功能以反映这一点。您仍需要重新分配this,但仅限于init函数

var myObject= {
        init: function(config){
            var _this = this;
            this.config=config;
            this.config.InputRadio.on('change',function(){
                _this.switchDiv(); // now "this" will refer to myObject, not the input
            });
        },
        switchDiv: function(){
            if (this.config.InputRadio.filter(":checked").val() === '1'){
                this.config.divYes.hide();
                this.config.divNo.show();
            }else{
                this.config.divYes.show();
                this.config.divNo.hide();
            }
        }
};

通过在匿名函数中包含对switchDiv的调用,您可以更好地维护this的上下文。

这是一个演示它的实际演示:

http://jsfiddle.net/VSdAL/

在相关说明中,建议在将self分配给变量以在回调或其他函数中使用时使用this。默认情况下,selfwindow.self的快捷方式,它是一个引用当前窗口的全局变量。您不希望重新分配使用self

删除其他代码的可能性

答案 1 :(得分:0)

ECMAScript 1.5(并非所有浏览器都支持)有一个方法Function.bind来绑定this值:

this.config.InputRadio.bind('click', this.switchDiv.bind(this));

当调用绑定的this时,myObject始终会引用switchDiv,您可以直接使用this.config而不是传递事件数据。

答案 2 :(得分:0)

除非您需要对象的公共API,否则我认为您最好不要创建这样的对象。将所有状态保持在隐藏范围内,如this fiddle

var createYesNoToggler = function(radioName, yesId, noId) {
    var divYes = $("#" + yesId), divNo = $("#" + noId),
        radios = $("input[name=" + radioName + "]");
    radios.click(function() {
        if ($(this).val() === "1") {
            divYes.show();
            divNo.hide();
        } else {
            divYes.hide();
            divNo.show();
        }
    });
};

createYesNoToggler("yesno", "yesDiv", "noDiv");

或者,如果你只需要那个,那么甚至不要公开这个功能:

(function(radioName, yesId, noId) {
    var divYes = $("#" + yesId), divNo = $("#" + noId),
        radios = $("input[name=" + radioName + "]");
    radios.click(function() {
        if ($(this).val() === "1") {
            divYes.show();
            divNo.hide();
        } else {
            divYes.hide();
            divNo.show();
        }
    });
}("yesno", "yesDiv", "noDiv"));

(但如果你不需要多个,那么后者可能会以更简单的方式完成。)