談JavaScript代碼封裝

前言瀏覽器

也算老生常談的問題了,再深刻搞一搞怎麼玩兒封裝,若是看到這篇文章的你,正好你也是追求完美的代碼潔癖狂者,那麼這篇文章相信很是適合你。緩存

舉一個例子,編寫一個Person類,具備name和birthday(時間戳)兩個屬性及對應的getter和setter方法,注意,setBirthday輸入的參數是日期字符串,如"2016-04-08"。getBirthday一樣獲得的也是日期字符串。那麼這個類是這樣的——安全

var Person = function(name, birthday) {
    this.name = name;
    this.birthday = birthday;   // timestamp
};

function getTimestampOfInput(dateString) {
    return new Date(dateString).getTime();
}

function getFormattedDay(timestamp) {
    var datetime = new Date(timestamp);
    var year = datetime.getFullYear();
    var month = datetime.getMonth() + 1;
    var date = datetime.getDate();
    return year + '-' + (String(month).length < 2 ? "0" + month : month) + "-"
            + (String(date).length < 2 ? "0" + date : date);
}

Person.prototype = {
    setName: function(name) {
        this.name = name;
    },
    getName: function() {
        return this.name;
    },
    /**
     * 設置生日
     * @param dateString
     */
    setBirthday: function(dateString) {
        this.birthday = getTimestampOfInput(dateString);
    },
    /**
     * 獲取生日
     * @returns {*}
     */
    getBirthday: function() {
        return getFormattedDay(this.birthday);
    }
};

若是採用面向過程的方式去寫,咱們須要藉助自執行匿名函數閉包的方式,如——服務器

// 經常使用模式一:單例/靜態 - 私有變量&共有方法
// 生成一我的
var person = (function() {
    // 私有變量
    var name = '';
    var birthday = new Date().getTime();    // 默認是時間戳方式
    // 共有方法
    return {
        setName: function(newName) {
            name = newName;
        },
        getName: function() {
            return name;
        },
        setBirthday: function(dateString) {
            // 私有函數
            function getTimestampOfInput() {
                return new Date(dateString).getTime();
            }

            birthday = getTimestampOfInput();
        },
        getBirthday: function() {
            return getFormattedDay(birthday);

            // 函數式 - 不訪問外界變量,沒有閉包的呈現
            // 有了輸入,便有了預想中的輸出,不保存狀態
            // 私有函數 - 已工具方法存在
            function getFormattedDay(timestamp) {
                var datetime = new Date(timestamp);
                var year = datetime.getFullYear();
                var month = datetime.getMonth() + 1;
                var date = datetime.getDate();
                return year + '-' + (String(month).length < 2 ? "0" + month : month) + "-"
                        + (String(date).length < 2 ? "0" + date : date);
            }
        }
    };
})();

person.setName('king');
console.log(person.getName());

person.setBirthday('2016-4-8');
console.log(person.getBirthday());

 

1、精分面向過程的寫法cookie

要知道,上面的面向過程person是一個單例,這種寫法更像是一種命名空間提供工具函數的方式,如——閉包

  1 /**
  2  * @file cookie
  3  * @author
  4  */
  5 define(function (require, exports, module) {
  6 
  7     /**
  8      * 操做 cookie
  9      *
 10      * 對外暴露三個方法:
 11      *
 12      * get()
 13      * set()
 14      * remove()
 15      *
 16      * 使用 cookie 必須瞭解的知識:
 17      *
 18      * 一枚 cookie 有以下屬性:
 19      *
 20      *    key value domain path expires secure
 21      *
 22      *    domain: 瀏覽器只向指定域的服務器發送 cookie,默認是產生 Set-Cookie 響應的服務器的主機名
 23      *    path: 爲特定頁面指定 cookie,默認是產生 Set-Cookie 響應的 URL 的路徑
 24      *    expires: 日期格式爲(Weekday, DD-MON-YY HH:MM:SS GMT)惟一合法的時區是 GMT,默認是會話結束時過時
 25      *    secure: 使用 ssl 安全鏈接時纔會發送 cookie
 26      *
 27      * 有點相似命名空間的意思
 28      *
 29      */
 30 
 31     'use strict';
 32 
 33     /**
 34      * 一小時的毫秒數
 35      *
 36      * @inner
 37      * @const
 38      * @type {number}
 39      */
 40     var HOUR_TIME = 60 * 60 * 1000;
 41 
 42     /**
 43      * 把 cookie 字符串解析成對象
 44      *
 45      * @inner
 46      * @param {string} cookieStr 格式爲 key1=value1;key2=value2;
 47      * @return {Object}
 48      */
 49     function parse(cookieStr) {
 50 
 51         if (cookieStr.indexOf('"') === 0) {
 52             // 若是 cookie 按照 RFC2068 規範進行了轉義,要轉成原始格式
 53             cookieStr = cookieStr.slice(1, -1)
 54                                  .replace(/\\"/g, '"')
 55                                  .replace(/\\\\/g, '\\');
 56         }
 57 
 58         var result = { };
 59 
 60         try {
 61             // Replace server-side written pluses with spaces.
 62             // If we can't decode the cookie, ignore it, it's unusable.
 63             // If we can't parse the cookie, ignore it, it's unusable.
 64             cookieStr = decodeURIComponent(cookieStr.replace(/\+/g, ' '));
 65 
 66             $.each(
 67                 cookieStr.split(';'),
 68                 function (index, part) {
 69                     var pair = part.split('=');
 70                     var key = $.trim(pair[0]);
 71                     var value = $.trim(pair[1]);
 72 
 73                     if (key) {
 74                         result[key] = value;
 75                     }
 76                 }
 77             );
 78         }
 79         catch (e) { }
 80 
 81         return result;
 82     }
 83 
 84     /**
 85      * 設置一枚 cookie
 86      *
 87      * @param {string} key
 88      * @param {string} value
 89      * @param {Object} options
 90      */
 91     function setCookie(key, value, options) {
 92 
 93         var expires = options.expires;
 94 
 95         if ($.isNumeric(expires)) {
 96             var hours = expires;
 97             expires = new Date();
 98             expires.setTime(expires.getTime() + hours * HOUR_TIME);
 99         }
100 
101         document.cookie = [
102             encodeURIComponent(key), '=', encodeURIComponent(value),
103             expires ? ';expires=' + expires.toUTCString() : '',
104             options.path ? ';path=' + options.path : '',
105             options.domain ? ';domain=' + options.domain : '',
106             options.secure ? ';secure' : ''
107         ].join('');
108     }
109 
110     /**
111      * 讀取 cookie 的鍵值
112      *
113      * 若是不傳 key,則返回完整的 cookie 鍵值對象
114      *
115      * @param {string=} key
116      * @return {string|Object|undefined}
117      */
118     exports.get = function (key) {
119         var result = parse(document.cookie);
120         return $.type(key) === 'string' ? result[key] : result;
121     };
122 
123     /**
124      * 寫入 cookie
125      *
126      * @param {string|Object} key 若是 key 是 string,則必須傳 value
127      *                            若是 key 是 Object,可批量寫入
128      * @param {*=} value
129      * @param {Object=} options
130      * @property {number=} options.expires 過時小時數,如 1 表示 1 小時後過時
131      * @property {string=} options.path 路徑,默認是 /
132      * @property {string=} options.domain 域名
133      * @property {boolean=} options.secure 是否加密傳輸
134      */
135     exports.set = function (key, value, options) {
136 
137         if ($.isPlainObject(key)) {
138             options = value;
139             value = null;
140         }
141 
142         options = $.extend({ }, exports.defaultOptions, options);
143 
144         if (value === null) {
145             $.each(
146                 key,
147                 function (key, value) {
148                     setCookie(key, value, options);
149                 }
150             );
151         }
152         else {
153             setCookie(key, value, options);
154         }
155     };
156 
157     /**
158      * 刪除某個 cookie
159      *
160      * @param {string} key
161      * @param {Object=} options
162      * @property {string=} options.path cookie 的路徑
163      * @property {string=} options.domain 域名
164      * @property {boolean=} options.secure 是否加密傳輸
165      */
166     exports.remove = function (key, options) {
167 
168         if (key == null) {
169             return;
170         }
171 
172         options = options || { };
173         options.expires = -1;
174 
175         setCookie(
176             key,
177             '',
178             $.extend({ }, exports.defaultOptions, options)
179         );
180     };
181 
182     /**
183      * 默認屬性,暴露給外部修改
184      *
185      * @type {Object}
186      */
187     exports.defaultOptions = {
188         path: '/'
189     };
190 
191 });
View Code

對於這個person單例或者理解爲一個普通的(命名空間)對象,咱們會發現兩個工具函數(用於birthday的格式化)——dom

getTimestampOfInput:服務於setBirthday這個方法
getFormattedDay:服務於getBirthday這個方法

 

1.1 將工具函數私有性封裝,利用閉包緩存該工具函數ide

會發現,每一次執行setBirthday,都會建立getTimestampOfInput這個函數,執行完setBirthday以後,getTimestampOfInput又會被銷燬;同理getFormattedDay方法。私有性,咱們作到了,可是每一次都須要去建立工具函數(getTimestampOfInput和getFormattedDay)。若是咱們想把工具函數僅僅執行一次,能夠這樣寫——函數

// 經常使用模式一:單例/靜態 - 私有變量&共有方法
// 生成一我的
var person = (function() {
    // 私有變量
    var name = '';
    var birthday = new Date().getTime();    // 默認是時間戳方式
    // 共有方法
    return {
        setName: function(newName) {
            name = newName;
        },
        getName: function() {
            return name;
        },
        setBirthday: (function() {
            // 私有函數
            function getTimestampOfInput(dateString) {
                return new Date(dateString).getTime();
            }
            return function(dateString) {
                getTimestampOfInput(dateString);
            };
        })(),
        getBirthday: (function() {
            // 函數式 - 不訪問外界變量,沒有閉包的呈現
            // 有了輸入,便有了預想中的輸出,不保存狀態
            // 私有函數 - 已工具方法存在
            function getFormattedDay(timestamp) {
                var datetime = new Date(timestamp);
                var year = datetime.getFullYear();
                var month = datetime.getMonth() + 1;
                var date = datetime.getDate();
                return year + '-' + (String(month).length < 2 ? "0" + month : month) + "-"
                        + (String(date).length < 2 ? "0" + date : date);
            }
            return function() {
                return getFormattedDay(birthday);
            };
        })()
    };
})();

要看見裏面用了一層閉包哦,也就是多須要耗損內存,但換來了性能上的優化。工具

 

1.2 將工具函數抽取爲私有

咱們繼續變態的走下去,把這兩個工具函數抽取出來,如——

// 經常使用模式一:單例/靜態 - 私有變量&共有方法
// 生成一我的
var person = (function() {
    // 私有變量
    var name = '';
    var birthday = new Date().getTime();    // 默認是時間戳方式
    // 函數式 - 不訪問外界變量,沒有閉包的呈現
    // 有了輸入,便有了預想中的輸出,不保存狀態
    // 私有函數 - 已工具方法存在
    function getFormattedDay(timestamp) {
        var datetime = new Date(timestamp);
        var year = datetime.getFullYear();
        var month = datetime.getMonth() + 1;
        var date = datetime.getDate();
        return year + '-' + (String(month).length < 2 ? "0" + month : month) + "-"
                + (String(date).length < 2 ? "0" + date : date);
    }
    // 函數式 - 不訪問外界變量,沒有閉包的呈現
    // 有了輸入,便有了預想中的輸出,不保存狀態
    // 私有函數 - 已工具方法存在
    function getTimestampOfInput(dateString) {
        return new Date(dateString).getTime();
    }
    // 共有方法
    return {
        setName: function(newName) {
            name = newName;
        },
        getName: function() {
            return name;
        },
        setBirthday: function(dateString) {
            birthday = getTimestampOfInput(dateString);
        },
        getBirthday: function() {
            return getFormattedDay(birthday);
        }
    };
})();

那麼這兩個工具方法一樣具備私有性,可是它可以服務的方法就更多了,全部對外暴露的方法(如未來有個新的方法getCreateDay),均可以使用這兩個工具函數。

 

1.3 將工具函數顯示聲明爲私有

OK,咱們看到上面的例子中,name,birthday,包含兩個工具方法都是私有的,咱們可使用"_"的方式來顯示聲明它是私有的,就能夠這樣去改裝——

// 經常使用模式一:靜態私有變量&共有方法
// 生成一我的
var person = {
    // 單例的私有屬性 - 或者可理解爲靜態變量
    _name: '',
    // 單例的私有屬性 - 或者可理解爲靜態變量
    _birthday: new Date().getTime(),    // 默認是時間戳方式
    // 工具函數
    _getTimestampOfInput: function(dateString) {
        return new Date(dateString).getTime();
    },
    // 工具函數
    _getFormattedDay: function(timestamp) {
        var datetime = new Date(timestamp);
        var year = datetime.getFullYear();
        var month = datetime.getMonth() + 1;
        var date = datetime.getDate();
        return year + '-' + (String(month).length < 2 ? "0" + month : month) + "-"
                + (String(date).length < 2 ? "0" + date : date);
    },
    // 共有方法
    setName: function(newName) {
        this._name = newName;
    },
    getName: function() {
        return this._name;
    },
    setBirthday: function(dateString) {
        this._birthday = this._getTimestampOfInput(dateString);
    },
    getBirthday: function() {
        return this._getFormattedDay(this._birthday);
    }
};

看起來還不錯,可是私有屬性仍是能夠被訪問的,如person._birthday,

 

1.4 利用private和public命名空間來實現私有和共有

那麼,咱們想要讓私有的屬性達到真正的私有,並藉助命名空間的方式,會有這個方式——

// 經常使用模式一:靜態私有變量&共有方法
// 生成一我的
var person = (function() {
    // 該對象保存靜態屬性
    // 保存單例的狀態
    var _private = {
        // 單例的私有屬性 - 或者可理解爲靜態變量
        _name: '',
        // 單例的私有屬性 - 或者可理解爲靜態變量
        _birthday: new Date().getTime(),    // 默認是時間戳方式
        // 工具函數
        getTimestampOfInput: function(dateString) {
            return new Date(dateString).getTime();
        },
        // 工具函數
        _getFormattedDay: function(timestamp) {
            var datetime = new Date(timestamp);
            var year = datetime.getFullYear();
            var month = datetime.getMonth() + 1;
            var date = datetime.getDate();
            return year + '-' + (String(month).length < 2 ? "0" + month : month) + "-"
                    + (String(date).length < 2 ? "0" + date : date);
        },
        getFormattedDayOfBirthday: function() {
            return this._getFormattedDay(this._birthday);
        }
    };

    // 共有對象
    var _public = {
        setName: function(newName) {
            _private._name = newName;
        },
        // 直接從_private對象中獲取
        getName: function() {
            return _private._name;
        },
        /**
         * 可直接操做_private中的靜態屬性
         * @param dateString
         */
        setBirthday: function(dateString) {
            _private._birthday = _private.getTimestampOfInput(dateString);
        },
        getBirthday: function() {
            return _private.getFormattedDayOfBirthday();
        }
    };

    return _public;
})();

_private和_public這兩個命名空間還不錯。在此基礎上,建議把工具函數拿出來,能夠這樣——

// 經常使用模式一:靜態私有變量&共有方法
// 生成一我的
var person = (function() {

    // 工具函數
    // 可供_private和_public對象共用
    function getTimestampOfInput(dateString) {
        return new Date(dateString).getTime();
    }
    // 工具函數
    // 可供_private和_public對象共用
    function getFormattedDay(timestamp) {
        var datetime = new Date(timestamp);
        var year = datetime.getFullYear();
        var month = datetime.getMonth() + 1;
        var date = datetime.getDate();
        return year + '-' + (String(month).length < 2 ? "0" + month : month) + "-"
                + (String(date).length < 2 ? "0" + date : date);
    }

    // 該對象保存靜態屬性
    // 保存單例的狀態
    var _private = {
        // 單例的私有屬性 - 或者可理解爲靜態變量
        _name: '',
        // 單例的私有屬性 - 或者可理解爲靜態變量
        _birthday: new Date().getTime()    // 默認是時間戳方式
    };

    // 共有對象
    var _public = {
        setName: function(newName) {
            _private._name = newName;
        },
        // 直接從_private對象中獲取
        getName: function() {
            return _private._name;
        },
        /**
         * 可直接操做_private中的靜態屬性
         * @param dateString
         */
        setBirthday: function(dateString) {
            _private._birthday = getTimestampOfInput(dateString);
        },
        getBirthday: function() {
            return getFormattedDay(_private._birthday);
        }
    };

    return _public;
})();

 

1.5 將工具函數就近於它的調用者

有些同窗很是喜歡將工具函數靠近與它的調用者,相似於這樣——

// 經常使用模式一:靜態私有變量&共有方法
// 生成一我的
var person = (function() {

    // 該對象保存靜態屬性
    // 保存單例的狀態
    var _private = {
        // 單例的私有屬性 - 或者可理解爲靜態變量
        _name: '',
        // 單例的私有屬性 - 或者可理解爲靜態變量
        _birthday: new Date().getTime()    // 默認是時間戳方式
    };

    _private.name = '';
    _private.birthday = new Date().getTime();    // 默認是時間戳方式

    var _public = {};

    _public.setName = function(newName) {
        _private._name = newName;
    };

    _public.getName = function() {
        return _private._name;
    };

    // 工具函數
    // 可供_private和_public對象共用
    function getTimestampOfInput(dateString) {
        return new Date(dateString).getTime();
    }
    _public.setBirthday = function(dateString) {
        _private._birthday = getTimestampOfInput(dateString);
    };

    // 工具函數
    // 可供_private和_public對象共用
    function getFormattedDay(timestamp) {
        var datetime = new Date(timestamp);
        var year = datetime.getFullYear();
        var month = datetime.getMonth() + 1;
        var date = datetime.getDate();
        return year + '-' + (String(month).length < 2 ? "0" + month : month) + "-"
                + (String(date).length < 2 ? "0" + date : date);
    }
    _public.getBirthday = function() {
        return getFormattedDay(_private._birthday);
    };

    return _public;
})();

 

1.6 將工具函數放入util等全局命名空間

一樣的,咱們發現這兩個工具函數具備通用性,能夠放置於全局,供全部函數使用,那麼就有這樣的方式,如——

// 這裏的工具類,能夠以單獨文件存在,供全局工程來使用
var util = {
    /**
     * 生日格式化顯示
     * @param timestamp
     * @returns {string}
     * @private
     */
    getFormattedDay: function(timestamp) {  // 模擬實現靜態方法
        var datetime = new Date(timestamp);
        var year = datetime.getFullYear();
        var month = datetime.getMonth() + 1;
        var date = datetime.getDate();
        return year + '-' + (String(month).length < 2 ? "0" + month : month) + "-"
                + (String(date).length < 2 ? "0" + date : date);
    },
    /**
     * 根據用戶輸入來獲取時間戳,如輸入'1995-10-05'
     * @param timestamp
     * @returns {string}
     * @private
     */
    getTimestampOfInput: function(dateString) {
        return new Date(dateString).getTime();
    }
};

var person = (function() {
    // 私有變量
    var name = '';
    var birthday = new Date().getTime();    // 默認是時間戳方式
    // 共有方法
    return {
        setName: function(newName) {
            name = newName;
        },
        getName: function() {
            return name;
        },
        setBirthday: function(dateString) {
            birthday = util.getTimestampOfInput(dateString);
        },
        getBirthday: function() {
            return util.getFormattedDay(birthday);
        }
    };
})();

上面這種方式,也是咱們最經常使用的方式,很直觀,易維護。

OK,那麼面向過程的寫法方式,就算是精分完了,很變態對不對?

總之,沒有嚴格的對錯,按照你認同喜歡的模式來。下面精分一下面向對象的寫法。

 

2、精分面向對象的寫法

面向對象的寫法,要注意prototype中的方法供全部實例對象所共有,且這裏的方法都是對實例狀態變動的說明,即對實例屬性的操做的變動。

 

2.1 不要把工具函數放入prototype中

基於前言裏面的例子,咱們經常不注意的將工具函數也都放在prototype當中,如——

// 多實例
var Person = function(name, birthday) {
    this.name = name;
    this.birthday = birthday;   // timestamp
};
Person.prototype = {
    setName: function(name) {
        this.name = name;
    },
    getName: function() {
        return this.name;
    },
    /**
     * 設置生日
     * @param dateString
     */
    setBirthday: function(dateString) {
        this.birthday = this._getTimestampOfInput(dateString);
    },
    // 工具函數
    _getTimestampOfInput: function(dateString) {
        return new Date(dateString).getTime();
    },
    /**
     * 獲取生日
     * @returns {*}
     */
    getBirthday: function() {
        return this._getFormattedDay(this.birthday);
    },
    // 工具函數
    _getFormattedDay: function(timestamp) {
        var datetime = new Date(timestamp);
        var year = datetime.getFullYear();
        var month = datetime.getMonth() + 1;
        var date = datetime.getDate();
        return year + '-' + (String(month).length < 2 ? "0" + month : month) + "-"
                + (String(date).length < 2 ? "0" + date : date);
    }
};

會看見上面的_getTimestampOfInput和_getFormattedDay兩個方法也都放置在了prototype當中,然而這裏的方法並無操做實例屬性,所以不該該將這類工具方法置於prototype當中。

 

2.2 不要將緩存變量放入this當中

還有一個你們經常犯的一個大錯誤,就是習慣性把各個方法間通信的變量放入到this當中,以下——

var Person = function(name, birthday) {
    this.name = name;
    this.birthday = birthday;   // timestamp
};

function getTimestampOfInput(dateString) {
    return new Date(dateString).getTime();
}

function getFormattedDay(timestamp) {
    var datetime = new Date(timestamp);
    var year = datetime.getFullYear();
    var month = datetime.getMonth() + 1;
    var date = datetime.getDate();
    return year + '-' + (String(month).length < 2 ? "0" + month : month) + "-"
            + (String(date).length < 2 ? "0" + date : date);
}

Person.prototype = {
    setName: function(name) {
        this.name = name;
    },
    getName: function() {
        return this.name;
    },
    /**
     * 設置生日
     * @param dateString
     */
    setBirthday: function(dateString) {
        this.birthday = getTimestampOfInput(dateString);
    },
    /**
     * 獲取生日
     * @returns {*}
     */
    getBirthday: function() {
        // 不要把緩存變量放置於this中
        this.birthdayOfFormatted = getFormattedDay(this.birthday);
        return this.birthdayOfFormatted;
    }
};

會看到,這裏的this.birthdayOfFormatted是一個緩存變量,並不能表明這個實例的某個狀態。好了,咱們回到正確的方式。

 

2.3 將工具函數就近於方法的調用者

// 多實例 - 抽取工具函數
var Person = function(name, birthday) {
    this.name = name;
    this.birthday = birthday;   // timestamp
};

Person.prototype.setName = function(name) {
    this.name = name;
};

Person.prototype.getName = function() {
    return this.name;
};

// 工具函數
function getTimestampOfInput(dateString) {
    return new Date(dateString).getTime();
}

Person.prototype.setBirthday = function(dateString) {
    this.birthday = getTimestampOfInput(dateString);
};

// 工具函數
function getFormattedDay(timestamp) {
    var datetime = new Date(timestamp);
    var year = datetime.getFullYear();
    var month = datetime.getMonth() + 1;
    var date = datetime.getDate();
    return year + '-' + (String(month).length < 2 ? "0" + month : month) + "-"
            + (String(date).length < 2 ? "0" + date : date);
}

Person.prototype.getBirthday = function() {
    return getFormattedDay(this.birthday);
};

在維護性方面略勝一籌,主要看我的的變成習慣。

 

2.4 將工具函數放入類命名空間中,充當類的靜態函數

// 多實例 - 抽取工具函數
var Person = function(name, birthday) {
    this.name = name;
    this.birthday = birthday;   // timestamp
};

// 工具函數 - 對外靜態變量
Person.getTimestampOfInput = function (dateString) {
    return new Date(dateString).getTime();
};

// 工具函數 - 對外靜態變量
Person.getFormattedDay = function(timestamp) {
    var datetime = new Date(timestamp);
    var year = datetime.getFullYear();
    var month = datetime.getMonth() + 1;
    var date = datetime.getDate();
    return year + '-' + (String(month).length < 2 ? "0" + month : month) + "-"
            + (String(date).length < 2 ? "0" + date : date);
};

Person.prototype = {
    setName: function(name) {
        this.name = name;
    },
    getName: function() {
        return this.name;
    },
    /**
     * 設置生日
     * @param dateString
     */
    setBirthday: function(dateString) {
        this.birthday = Person.getTimestampOfInput(dateString);
    },
    /**
     * 獲取生日
     * @returns {*}
     */
    getBirthday: function() {
        return Person.getFormattedDay(this.birthday);
    }
};

我我的比較推薦這種寫法,固然也能夠把工具函數放入某個相似於util的命名空間中,供全局調用。

 

2.5 將工具函數放入util等全局命名空間

// 這裏的工具類,能夠以單獨文件存在,供全局工程來使用
var util = {
    /**
     * 生日格式化顯示
     * @param timestamp
     * @returns {string}
     * @private
     */
    getFormattedDay: function(timestamp) {  // 模擬實現靜態方法
        var datetime = new Date(timestamp);
        var year = datetime.getFullYear();
        var month = datetime.getMonth() + 1;
        var date = datetime.getDate();
        return year + '-' + (String(month).length < 2 ? "0" + month : month) + "-"
                + (String(date).length < 2 ? "0" + date : date);
    },
    /**
     * 根據用戶輸入來獲取時間戳,如輸入'1995-10-05'
     * @param timestamp
     * @returns {string}
     * @private
     */
    getTimestampOfInput: function(dateString) {
        return new Date(dateString).getTime();
    }
};


// 多實例 - 抽取工具函數
var Person = function(name, birthday) {
    this.name = name;
    this.birthday = birthday;   // timestamp
};

Person.prototype = {
    setName: function(name) {
        this.name = name;
    },
    getName: function() {
        return this.name;
    },
    /**
     * 設置生日
     * @param dateString
     */
    setBirthday: function(dateString) {
        this.birthday = util.getTimestampOfInput(dateString);
    },
    /**
     * 獲取生日
     * @returns {*}
     */
    getBirthday: function() {
        return util.getFormattedDay(this.birthday);
    }
};

好啦,整個面向對象的寫法方式介紹到這兒。

總之,歸於一點——要知道什麼方法能夠當作工具函數處理,併合理地放置工具函數的位置。

 

3、總結

整篇文章主要圍繞工具函數的寫法展開,模式不一樣,沒有對與錯,依照自身的編碼習慣而定。歡迎看到文章的博友補充。

相關文章
相關標籤/搜索