将javascript代码封装在全局对象中以获得更清晰的代码

时间:2011-03-06 11:23:34

标签: javascript jquery jquery-ui scope

我正在尝试使用jQuery和jQueryUI的datepicker,内联模式。

我想将所有代码放在一个全局对象中,并将其用于datepicker init函数(beforeShowDay,changeMonthYear)。 我也有一些实用功能。

我被困了,因为我真的不知道该怎么办 我已经阅读了很多文章,教程,stackoverflow线程 - 特别是在this范围等,但现在我不知道从哪里开始!

这是我到目前为止所做的:

var Calendar = (function() {
var obj = this;

var calendar = {
    datescache: [],
    bsd: function (date) {
        var offset =  this.formatNum(date.getMonth()+1)+'-'+this.formatNum(date.getDate());
        if (thedate[offset] != undefined) {
            return [true, 'bold', thedate[offset] + ' événement(s)'];
        } else {
            return [true];
        }
    },
    formatNum: function (i) {return ('0'+i).slice(-2);},
    getEventsForDate: function(year, month, inst) {
        var date = this.datescache;
        if (this.datescache[month] === undefined) {
            console.warn('uncached: '+month);
            $.ajax({
                url: '/event/get-event-count/year/'+year+'/month/'+month+'/format/json',
                success: function (resp) {
                    date[month] = resp.events;
                },
                async: false
            });
        }
        console.log('return: '+month);
        return date[month];
    }
}

return calendar;    
})();


$('#calendar').datepicker({
    dateFormat: "dd\/mm\/yy",
    showOtherMonths: true,
    selectOtherMonths: true,
    beforeShowDay: Calendar.bsd,
    onChangeMonthYear: Calendar.getEventsForDate,
});

当然我在该行有一个错误:

var offset =  this.formatNum(date.getMonth()+1)+'-'+this.formatNum(date.getDate());  

因为this引用了datepicker对象,因为我们在回调函数beforeShowDay中,小心地将datepicker实例传递给函数this。 但我需要this来引用我的效用函数,例如formatNum

  • 我应该从哪里开始?
  • 尝试扩展datepicker对象(尚未尝试)是否更好?

提前感谢您的帮助!

编辑1

好的,有了更多的阅读和第一个答案,我设法得到了一些工作:

var Calendar = (function() {
  var calendar = function() {
    var self = this;

    this.datescache = [];

    this.bsd = function (date) {
       [[... I use for instance self.datescache ...  ]]
    }

    [[...]]

  };
  return new calendar();
})();

这似乎工作正常。

  • 是否还需要全局封装?

再次感谢!

1 个答案:

答案 0 :(得分:0)

对于回调和其他函数中的操作this,有几个选项。

而不是在函数内调用this,您可以调用thatself之类的别名。在您的情况下,变量obj = this已经是别名,因此您可以调用obj.formatNum

另一个选项是Function.bind,允许您这样做:

foo : (function() {
    ...
}).bind(obj),
...

请注意Function.bind是ES5的事情。您可以改为使用来自下划线的_.bind_.bindAll

this范围起作用的另一个选择就是这样做

beforeShowDay: function() {
    Calendar.bsd();
},
onChangeMonthYear: function() {
    Calendar.getEventsForDate();
},

这里的不同之处在于传递函数(当调用时将使用不同的this对象调用),传递函数调用函数 ON 您自己的日历因此强制this成为Calendar

请参阅:

var f = function() { console.log(this); }
var a = {
    b: f
};
var c = {}
c.d = a.b;
c.e = function() {
    a.b();
};

f(); // window
a.b(); // a
c.d(); // c
c.e(); // calls a.b(); so a

this范围是您调用方法的任何对象。