Javascript的function.call方法

摘要:Javascript的function.call方法

之前在擴充jQuery的datepicker的時候,對於Javascript的this蠻頭痛的,

當我呼叫一個方法的時候,this會指到我目前作用中的context,

不過有時候我並不希望是這樣的狀況,

當我擴充datepicker的時候,我需要去取代一些函式,但是我又需要在新的函式中去使用這些舊的函式,

當我這樣使用的時候,舊的函式的this就不再是原本的context了,

這讓我採用另一種方式來處理,就是將舊的函式rename,

這樣讓人感覺美中不足,因為這樣會使得舊的函式佔用一個方法名稱,而這個方法有覆寫到其他方法的風險,

在偶然的狀況下,找到了這樣的功能,

這讓我有相見恨晚的感覺,

我們可以利用function.call來執行一個函式,並且改變其this所指的context,

利用這個方法,我可以將舊的函式隱藏在我的程式區塊中,而不需要利用rename的方法來處理這類的問題。

---------------------------------------------------------------------------------------------------------------------------------------------------------

新的datepicker擴充:

(function(_jQueryInit)

{

    jQuery.fn.init = function(selector, context)

    {

       return (jQuery._this = new _jQueryInit(selector, context));

    };

})(jQuery.fn.init);

 

(function($)

{

    var baseGenerateMonthYearHeader = $.datepicker._generateMonthYearHeader;

    $.datepicker._generateMonthYearHeader = function(inst, drawMonth, drawYear, minDate, maxDate,

       selectedDate, secondary, monthNames, monthNamesShort)

    {

       var title = $(baseGenerateMonthYearHeader.call($.datepicker,

           inst, drawMonth, drawYear - 1911, minDate, maxDate,

           selectedDate, secondary, monthNames, monthNamesShort));

       title.children(".ui-datepicker-year").html($._this.html() + "");

 

       title.html(title.html().replace(

           /(<span class=ui-datepicker-month>.*<\/span>)(.*)(<span class=ui-datepicker-year>.*<\/span>)/ig,

           "$3$2$1"));

 

       return $("<div/>").append(title).html();

    };

 

    $.datepicker._setDateFromField = function(inst)

    {

       var dateFormat = this._get(inst, 'dateFormat');

       var dates = inst.input ? inst.input.val() : null;

       inst.endDay = inst.endMonth = inst.endYear = null;

       var date = defaultDate = this._getDefaultDate(inst);

       var settings = this._getFormatConfig(inst);

       try

       {

           var dateArr = dates.split("/");

           var year = parseInt(dateArr[0]) + 1911;

           var month = parseInt(dateArr[1]);

           var day = parseInt(dateArr[2]);

           date = this.parseDate(dateFormat, this.formatDate(dateFormat, date, settings), settings) || defaultDate;

       } catch (event)

       {

           this.log(event);

           date = defaultDate;

       }

       inst.selectedDay = date.getDate();

       inst.drawMonth = inst.selectedMonth = date.getMonth();

       inst.drawYear = inst.selectedYear = date.getFullYear();

       inst.currentDay = (dates ? date.getDate() : 0);

       inst.currentMonth = (dates ? date.getMonth() : 0);

       inst.currentYear = (dates ? date.getFullYear() : 0);

       this._adjustInstDate(inst);

    };

 

    $.datepicker._formatDate = function(inst, day, month, year)

    {

       if (!day)

       {

           inst.currentDay = inst.selectedDay;

           inst.currentMonth = inst.selectedMonth;

           inst.currentYear = inst.selectedYear;

       }

       var date = (day ? (typeof day == 'object' ? day :

              this._daylightSavingAdjust(new Date(year, month, day))) :

              this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));

       return (date.getFullYear() - 1911) + "/" +

              (date.getMonth() < 10 ? "0" + (date.getMonth() + 1) : (date.getMonth() + 1)) + "/" +

              (date.getDate() < 10 ? "0" + date.getDate() : date.getDate());

    };

})(jQuery);