JavaScript對象及繼承教程
一、 類(lèi)與對象
在 JavaScript 世界里,關(guān)于面向對象第一個(gè)要澄清的概念就是類(lèi)。對象都是有類(lèi)來(lái)定義的,通過(guò)類(lèi)來(lái)創(chuàng )建對象就是我們所熟悉的實(shí)例化。然而,在 JavaScript 中別沒(méi)有真正的類(lèi),對象的定義就是對象自身。而 ECMA-262 干脆把這種妥協(xié)的方式稱(chēng)作為對象的調和劑。為了方便理解,我通常把這個(gè)發(fā)揮類(lèi)的作用的調和劑稱(chēng)為類(lèi)。
二、 內置對象
1、 Array類(lèi)
數組在 js 中是非常常用的一種數據結構,由于其靈活性和易用性,合理的使用數組可以幫助我們更好的實(shí)現相應的功能。
讓我們先看 Array 對象的創(chuàng )建吧
第一種:var arr = new Array(10);
該方法在實(shí)際的使用當中并不那么的實(shí)用,與很多編譯型語(yǔ)言不同, js 數組的長(cháng)度是可變的,不但增強了靈活性,還給我們有了更多好的選擇。
第二種:var arr = new Array("one","two","three");
使用 new 方式創(chuàng )建數組的方法一般多為這兩者,當然也可以使用 new Array() 創(chuàng )建一個(gè)空的數組對象。通常情況下,我推薦如下的方法
第三種:var arr = ["one","two","three"];
使用數組的字面量方式創(chuàng )建一個(gè)數組對象,不但簡(jiǎn)潔易讀,而且幾乎完全等價(jià)于使用 new 方式創(chuàng )建數組對象的效果。數組對象有很多好用的方法,接下來(lái)我們就一起看看這個(gè)數組對象的強大功能吧。
首先要介紹的是 push 方法,學(xué)過(guò)數據結構的朋友都知道 push 意味著(zhù)什么,沒(méi)錯,他的出現讓數組能夠實(shí)現棧的數據結構(同時(shí)需要配合 pop 方法)。 push 方法幫助我們緊湊的添加數組元素。前面提到j(luò )s中的數組是長(cháng)度是可變的,則我們可以添加元素。既然可以通過(guò) arr[length] = newValue; 來(lái)給 arr 添加一個(gè)新元素并放置于數組尾。更好的辦法就是使用 push 方法。 arr.push(newValue); 怎么樣,使用他比你還要通過(guò)數組長(cháng)度來(lái)賦新值方便多了吧。在這里有一點(diǎn)需要注意。請看下面的代碼:
var arr = [];
arr[4] = 5;
alert(arr.length == 5);
alert(arr); //alert : ,,,,5
當我們需要給指定數組位置賦予指定的值的時(shí)候,這種賦值就顯得十分有用了,比如在用于裝箱排序的時(shí)候。
pop 方法則是實(shí)現與 push 相反的作用,返回數組的最后一個(gè)元素,并出棧。
var arr = [1,2,3,4,5];
var ele = arr.pop();
alert(ele == 5);
alert(arr.length == 4);
數組對象的 toString 和 valueOf 方法比較人性化的重寫(xiě)了,它的實(shí)現是把每一項都調用 toString 方法,然后用半角逗號(,)連接每一項。那么:
var arr = [1,2,3,4,5];
alert(arr);//output:1,2,3,4,5
toLocaleString 方法在這里不做詳細說(shuō)明了,他的效果與 toString 方法類(lèi)似,只是每項調用 toLocateString 方法。
如果你想使用個(gè)性化的分隔符來(lái)顯示數組元素,那么 join 方法可能會(huì )更加的適合。比如:
var city = ["上海","北京","天津","重慶","深圳"];
alert(city.join("|"));//output:上海|北京|天津|重慶|深圳
由此可見(jiàn) join 是把數組元素轉換為一個(gè)字符串。在介紹字符串的時(shí)候我們將再次看到 join 方法的使用。
concat 方法和 slice 方法是又一對好用的方法,這兩個(gè)方法的特殊之處在于 String 對象也擁有他們。當我們希望給一個(gè)數組添加多個(gè)數組元素的時(shí)候,使用 push 可能就顯得有些冗余和復雜了,而且也會(huì )讓 coding 變得不那么有意思了。好在我們有 concat 方法,該方法將其參數們按序加入數組元素中。如:
var arr = [1,2,3,4,5];
arr = arr.concat(6,7,8,9);
alert(arr.length == 9);
注意, concat 并不修改數組對象本身,而是將數組元素與 concat 方法的數組元素合并后返回。所以需要給數組元素進(jìn)行賦值運算才行。
slice 方法則是從數組對象中返回一個(gè)子數組。該子數組是從 slice 方法的第一個(gè)參數所指位置至第二個(gè)參數所指的位置。這是一個(gè)半開(kāi)半閉區間 [a,b) 。如:
var arr = [1,2,3,4,5];
var arr1 = arr.slice(1,3);
alert(arr1); //output:2,3
alert(arr); //output:1,2,3,4,5
好了, slice 和 concat 方法一樣不是修改數組對象本身。同時(shí)參數1,3表示從位置1到位置3的半開(kāi)半閉區間的子數組。
剛才討論了后進(jìn)先出的棧操作,現在我們來(lái)看看先進(jìn)先出的隊列操作吧。進(jìn)列使用 push 方法沒(méi)有問(wèn)題,那么出列呢。是 shift ,他刪除數組對象的第一個(gè)元素并返回:
var arr = [1,2,3,4,5];
var ele = arr.shift();
alert(ele); //output:1
alert(arr.length);//output:4
另外一個(gè)還有一個(gè)方法,叫 unshift ,他將新元素插入數組對象的第一項,究其功能與 shift 是相反的操作。
sort 方法很靈活,使用好了,他可以給數組元素以任意你想要的排序方式來(lái)進(jìn)行排序。因為 sort 方法接收一個(gè)匿名函數(其實(shí),它同樣可以接收一個(gè)非匿名的函數,但是通常不推薦為此而創(chuàng )建一個(gè)這樣的命名函數,除非該函數可重用)作為自己的排序的條件。比如:
Object.prototype.toString = function(){
var str = '';
for(var item in this) {
str += item + ":" + this[item] + ",";
}
return str.length?str.substr(0,str.length-1):str;
};
var arr = [{key:3,value:"three"},{key:1,value:"one"},{key:2,value:"two"}];
arr.sort(function(a,b){
return a.key - b.key;
});
alert(arr);//output:key:1,value:one,key:2,value:two,key:3,value:three
我們先不去糾結 Object.prototype.toString 方法,他的左右就是將對象遍歷使之可以輸出為鍵值對格式字符串,在介紹原型鏈的時(shí)候會(huì )再次提到。我們可以看到 sort 方法通過(guò)這個(gè)匿名方法讓我們可以根據 key 屬性來(lái)進(jìn)行排序。那就讓我們來(lái)看看這個(gè)匿名方法吧。
function(a,b) {
return a.key - b.key;
};
可以看到,這個(gè)方法接收2個(gè)參數,然后對參數的自身或某個(gè)屬性進(jìn)行比較,然后返回比較結果,他們的比較結果與排序對應關(guān)系如下:
如果 paramA - paramB > 0,return 正數 ,則 b 排在 a 的前面
如果 paramA - paramB < 0,return 負數 ,則 b 排在 a 的后面
如果 paramA - paramB = 0,return 0 ,則順序不變。
上面的實(shí)現是順序排序,那么 倒序 呢?對, return paramB - paramA;
reverse 方法可以將數組對象反轉。他和 sort 方法一樣是修改數組對象內部元素順序的。
最后我們看看 splice 方法,他是替換和刪除數組對象元素的方法。根據參數的改變而擁有不同的實(shí)現結果。 splice(pos,count[,insertParams]);pos 參數是刪除元素的第一個(gè)項的位置, count 參數是刪除元素的個(gè)數,當為0時(shí)則不刪除(不刪除還要這個(gè)方法干嘛,別著(zhù)急,往下看), insertParams 則是參數列表,這些參數是即將插入的元素集合。插入的位置為 pos 。那么就出現了以下幾種情況了。
1、 insertParams 忽略時(shí),該方法就是刪除數組元素
2、 當 count 參數為0時(shí),該方法將只是將 insertParams 插入到 pos 位置
3、 當 count 參數不為0且 insertParams 不忽略時(shí),該方法就是刪除 pos 位置開(kāi)始的 count 個(gè)元素,并替換 insertParams 參數集合。
2、 Math類(lèi)
我們花了很大的篇幅來(lái)介紹數組類(lèi),我要再次強調一點(diǎn),這個(gè)類(lèi)只是為了介紹方便強加于它的一個(gè)名字,實(shí)際上他們也只是對象。而非真正的類(lèi)。
Math 類(lèi)的使用范圍相對狹窄,因為他作為一個(gè)數學(xué)計算的類(lèi),而非一個(gè)數據結構類(lèi),但是我們也看到了 Math.random 以及各種取整等常用方法。因此我們不妨花些時(shí)間來(lái)看看他們,但是如果你對此興趣不大,那么看完 random 方法之后就可以跳到下一節去,以后用到的時(shí)候再翻手冊就可以了。
Math 通常是一個(gè)“靜態(tài)”類(lèi),因為沒(méi)有人會(huì )實(shí)例化一個(gè) Math 對象,而是直接使用其“靜態(tài)”方法,有些資料直接稱(chēng)它為 Math 對象,在這里我們不妨稱(chēng)它為“靜態(tài)”類(lèi)吧。
首先我必須介紹 random 方法,因為他常用且太有用了。在制造隨機事件的時(shí)候他總是不可或缺,同樣在防止緩存上他也顯得很有用處。 Math.random 方法返回的是一個(gè) 0到1 之間的開(kāi)區間浮點(diǎn)數,即 (0,1) ,他的使用非常簡(jiǎn)單,唯一需要注意的是,當我們取整的時(shí)候對 floor 和 ceil 方法的篩選時(shí)需要謹慎,前者使得 random 間接轉換為前閉后開(kāi)區間,而后者則是前開(kāi)后閉區間。假如我們現在需要一個(gè)取1-100的隨機數,那么有如下的兩種常用解決方案
方法一:Math.ceil(Math.random*100);
方法二:Math.floor(Math.random*100)+1;
ceil 方法和 floor 方法都是用來(lái)取整的數學(xué)方法,根據單詞含義我們可以理解,前者是向上取整,而后者則是向下取整。
當我們從一個(gè)連續的數組對象中隨機選擇一個(gè)數組元素時(shí),我們可以借助 random 輕松的來(lái)幫我們挑選:
["ipad","iphone","ipod touch","ipod nano","macbook"][Math.ceil(Math.random()*4)];
這個(gè)例子中,我直接使用的是數組字面量,一開(kāi)始你可能會(huì )覺(jué)得費解或者不易理解,當你深入以后你會(huì )發(fā)現原來(lái) JavaScript 是如此的方便、簡(jiǎn)潔、靈活。
前面我們介紹了 ceil 和 floor 方法的取整,那么當我們想要接近舍入時(shí)呢,我們可以使用 Math.round 方法,他在取整時(shí)根據數值進(jìn)行靠近取整。比如 Math.round(5.4) 返回的是 5 。那么如果 Math.round(5.5) 呢,答案是 6 而不是 5 。關(guān)于這點(diǎn)需要有所了解。好吧我承認我較真了,但是知道了他有什么壞處呢。
當我們想從 2 個(gè)數中取得較小或者較大的數的時(shí)候怎么做呢?
if(a>b) {
return a;
} else {
return b;
}
我們多慮了。 Math 提供了 Math.max 和 Math.min 方法來(lái)幫助我們解決這個(gè)問(wèn)題。
Math 還有一大堆的“靜態(tài)”方法和屬性。在這里我就不一一列舉了,當我們要進(jìn)行數學(xué)計算的時(shí)候不妨去查查手冊。
3、 String類(lèi)
字符串對象的使用頻率恐怕比數組對象有過(guò)之而無(wú)不及,為什么我要放到后面來(lái)說(shuō)呢,其實(shí)是因為對于字符串,我們要說(shuō)的更多,而可擴展的方法和工具函數也更加豐富。我們一起先來(lái)看看 String 類(lèi)本身吧。
創(chuàng )建一個(gè)字符串對象有以下幾種方法:
方法一:var str = new String("Hello World");
方法二:var str = String("Hello World");
方法三:var str = "Hello World";
和數組對象一樣,我推薦大家使用最后一種方法,及字符串字面量。關(guān)于是否有 new 的區別,周愛(ài)民老師的博客中有過(guò)很詳細的解釋?zhuān)瑫r(shí),如果你一直讀下去,在介紹自定義對象的時(shí)候也會(huì )提到 new 運算符。
String 對象有且只有一個(gè)屬性 length ,他返回字符串的長(cháng)度,在這里我們必須要弄明白 JavaScript 是 unicode 編碼,那么漢字和英文都當作一個(gè)字符長(cháng)度來(lái)處理,之所以提到這個(gè)是因為曾經(jīng)遇到不止一位朋友在論壇提問(wèn)這個(gè)問(wèn)題,呵呵,動(dòng)手的必要性啊。那么如果我們非要把漢字當作 2 個(gè)字符長(cháng)度來(lái)計算呢?這就帶來(lái)了我們第一個(gè)自定義方法。
String.prototype.getLength = function(isSplit){
if(isSplit) {
return this.replace(/[^\u0000-\u00FF]/g,"tt").length;
}
else {
return this.length;
}
};
該方法通過(guò)傳遞一個(gè) Boolean 類(lèi)型的參數,如果為真則將非半角字符、數字、英文字母分割為 2 個(gè)長(cháng)度來(lái)求長(cháng)度,不用擔心這個(gè)分割,他并不會(huì )修改字符串對象本身。如果為假,則直接返回 length 屬性值。由于介紹方法不是根據方法的字符排列順序而來(lái),如果作為字典,我想還是 w3school 更合適,因為我是根據作用的不同和關(guān)聯(lián)性來(lái)進(jìn)行介紹。 ok ,介紹完了 length 屬性,我們看看字符串查找吧。
indexOf 和 lastIndexOf 方法。
這兩個(gè)方法從是從字符串中查找一個(gè)字符或字符子串,區別在于查找方向,前者是從位置 0 處開(kāi)始查找,并返回第一個(gè)查找到的位置,后者從位置 length-1 處開(kāi)始查找,并返回第一個(gè)查找到的位置。如果查找不到呢,返回 -1 。例如
var str = "了解面向對象編程和基于對象編程是一個(gè)基礎理論";
alert(str.indexOf("對象")); //output:4
alert(str.lastIndexOf("對象"));//output:11
alert(str.indexOf("過(guò)程"));//output:-1
從輸出的結果我可以得到以下結論:
1、 字符位置是從 0 開(kāi)始索引
2、 即使是從后往前查找,返回位置時(shí)也還是位置 0 開(kāi)始計算
3、 當在字符串中索引不到該子串時(shí),返回 -1 值。
charAt 和 charCodeAt 方法根據一個(gè)位置索引來(lái)返回字符,其中前者是返回字符本身,后者返回字符編碼。我們簡(jiǎn)單的看個(gè)例子后結束他們:
var str = "了解面向對象編程和基于對象編程是一個(gè)基礎理論";
alert(str.charAt(5)); //output:象
alert(str.charCodeAt(5));//output:35937
接下來(lái)輪到 slice , substr 和 substring 方法,說(shuō)實(shí)話(huà)很多熟悉 JavaScript 的程序員也經(jīng)常會(huì )混淆兩者的用法,并非是我夸張,而是 substring 和很多后臺語(yǔ)言的 substring 方法區別很大的哦。先看看 slice 方法。
slice(start[,end]) 方法需要提供至少一個(gè)整數參數,作用是返回從 start 的位置開(kāi)始到 end 位置的字符子串。接下來(lái)幾句話(huà)請仔細看清楚了,以防造成曲解,當參數 start 為負數的時(shí)候他將從字符串尾部開(kāi)始計算,當 end 沒(méi)有指定時(shí), end 即為字符串的結尾。如果為負數呢,他也要從字符串尾部開(kāi)始計算。所以當我們需要一個(gè)字符串的之后 3 個(gè)字符時(shí)只需 slice(-3); 由此可見(jiàn),合理的使用負數讓我們的程序變得簡(jiǎn)單。但是在此之前,請確保自己了解了他的作用。
據我所知的編程語(yǔ)言中,有很大一部分的 substring 方法設計為 substring(beginposition,length) ,而在 JavaScript 中正好也有這么一個(gè)方法,可惜真正與之對應的是 substr 方法。 substr(pos[,length]) 方法中,如果 pos 為負數,則與 slice 的負數解釋相同, length 省略時(shí)與 slice 的 end 省略也相同。
到了 substring 方法, substring(from[,to]); 從定義上就可以看到,后一個(gè)參數是一個(gè)位置,而非長(cháng)度,因此他更像 slice ,但是與之有一點(diǎn)重要的區別,那就是 substring 方法不包含 to 位置。即是一個(gè)半開(kāi)半閉區間。另一個(gè)區別是 substring 不支持負向位置,如果第一個(gè)參數為負數,那么就是從位置 0 開(kāi)始。后一個(gè)位置如果是負數,則返回空串,如果第二個(gè)參數小于第一個(gè)參數,那么同樣返回空串,但是如果相等呢,還是空串,因為這是一個(gè)半開(kāi)半閉區間 [from,to) 。
另外幾個(gè)查找的方法 :match 、 search 將在后面介紹正則表達式和 RegExp 類(lèi)的時(shí)候詳細介紹。替換方法 replace 也將在介紹正則表達式時(shí)介紹。另外一對有用的方法是 toLowerCase 和 toUpperCase 。他們就是將字符串進(jìn)行大小寫(xiě)轉換的。
字符串操作的另一個(gè)領(lǐng)悟的連接字符串。字符串對象是長(cháng)度不可變的,仔細回顧下之前所有的方法中沒(méi)有一個(gè)是修改對象本身的方法。關(guān)于這點(diǎn)將于稍后一個(gè)思考題單獨會(huì )展開(kāi)來(lái)介紹?,F在你要做的就是知道這點(diǎn)。字符串對象的連接方法常見(jiàn)的三種,第一種是使用 concat 方法,在介紹 Array 類(lèi)的時(shí)候我們也見(jiàn)過(guò)這個(gè)方法,他們其實(shí)是一樣的東西,連接字符串為一個(gè)新串,另外字符串對象重載了 + 號運算符,用來(lái)簡(jiǎn)化連接操作,因此 "abc"+"de" == "abcde"; 還有一個(gè)方法是借助 Array 對象中的 push 和 join 方法連接字符串。
var arr = [];
for(var i = 0; i < 10; i++) {
arr.push("<img alt=\"test\" src=\"pic" + i + ".jpg\" />");
}
arr = arr.join("");
這種方法很類(lèi)似與 C# 中的 StringBuilder 的 append 和 ToString 方法,而好處也很類(lèi)似。不要忘了在 join 的方法中加上參數""哦,否則的話(huà),多出的逗號可能就有點(diǎn)事與愿違了。為了方便操作,我們通常還會(huì )擴展一個(gè)方法來(lái)模擬 printf(in c) 和 format(in c#):
function formatString() {
var args = arguments;
if(args.length > 1) {
return args[0].replace(new RegExp("\{([0-" + (args.length-2).toString() + "])\}","g"),function(s,m){
return args[+m+1];
});
}
}
首先我要說(shuō)明,這個(gè)方法與原來(lái)的方法相比丑陋了許多,但是更容易理解,其次,這個(gè)方法有自身的 bug 存在,即當參數過(guò)多(>10)時(shí),正則表達式將不能正確運轉。因此我們換個(gè)解決方案來(lái)解決這個(gè) bug (感謝zswang 的仔細,下面的解決方案也是仿照zswang的。)
function formatString(str,params) {
return str.replace(/\{(\d+)\}/g,function(s,m){
return params[+m];
});
}
alert(formatString("{0} is {1} old",['JeeChang',25]));
JavaScript 中沒(méi)有一個(gè) trim 方法,讓我們很是苦惱,沒(méi)有例外,我們自己寫(xiě)一個(gè) trim 方法吧
String.prototype.trim = function(which){
var pattern = {
"left":"^\\s*",
"both":"^\\s*|\\s*$"
}
return this.replace(new RegExp(pattern[which],'g'),"");
};
字符串的操作一直都不僅限于此,比如字符串截取往往還有這樣的需求,即我們在瀏覽器顯示的時(shí)候往往需要根據全半角來(lái)截斷字符串,但是最后一個(gè)字符是全角的話(huà)則需要全部截斷??瓷先ヒ欢ê軓碗s吧。沒(méi)關(guān)系我們來(lái)添加這個(gè)方法。
String.prototype.splitCount = function(count){
var str = this;
var signs = ['~','!','|','`',':','$','#','&','*','@','.','?'];
var sign = '';
for(var i = 0; i < signs.length; i++) {
if(str.indexOf(signs[i]) < 0) {
sign = signs[i];
break;
}
}
str = str.replace(/[^\u0000-\u00FF]/g,sign + sign);
var ig = count;
for(var i = 0; i < count; i++) {
if(str[i] == sign)
ig-=0.5;
}
return this.substr(0,Math.floor(ig));
};
這個(gè)方法很可惜,替換字符不夠全面,如果恰巧這些字符都存在于其中,那么結果就很可悲了。所以這個(gè)方法不是那么的可靠。其實(shí)可以通過(guò)初步判斷總字符長(cháng)度來(lái)截取掉后面的字符串然后再查找是否有替換字符。這樣概率就相對小些。
介紹完了數組對象和字符串對象之后,我們看下面一個(gè)例子:
var a = "abc";
var b = "abc";
alert(a.valueOf() === b.valueOf);
alert(a.toString() === b.toString());
alert(a.valueOf() == b.valueOf());
var arr1 = ['a','b','c'];
var arr2 = ['a','b','c'];
alert(arr1.toString() === arr2.toString());
alert(arr1.valueOf() === arr2.valueOf());
請問(wèn)輸出結果是什么呢?
4、 Date類(lèi)
日期類(lèi)恐怕是我見(jiàn)過(guò)最無(wú)奈的JavaScript內置類(lèi)(對象)。因為他的瀏覽器不同表現,時(shí)間日期的操作處理都顯得那么的不友好。幸好,JavaScript固有的機制可以讓我們自己來(lái)解決這些問(wèn)題。不過(guò)在此之前我們還是先大致了解下他的一些方法和屬性。
創(chuàng )建一個(gè)日期對象可以有這些方法
方法一:var d = new Date(ms);//ms代表從1970.1.1凌晨0點(diǎn)的毫秒數
方法二:var d = new Date(year,month[,day,hour,minute,second,millisecond]);
方法三:var d = new Date("localDateString");//這里不是那么的通用。2011/5/5格式相對通用
如果我們需要創(chuàng )建一個(gè)當前時(shí)間的日期對象。直接new Date()用無(wú)參數的構造函數即可。當然我們不能忽略這個(gè)new,前面提到String和Array可以省略,然而這里千萬(wàn)不能這樣做。因為Date()的結果是瀏覽器實(shí)現的一個(gè)日期對象的toString返回的表示日期的字符串。故此,這里兩者不能混用。
日期對象的方法大致分為獲取和設置日期時(shí)間的某一(幾)個(gè)部分。獲取方法相對好用一些,然后設置方法則顯得不那么夠用。這里有幾個(gè)需要拿出來(lái)先說(shuō)說(shuō)。
getDate/setDate。該方法操作的是天數,而非日期值。這個(gè)還是有點(diǎn)不大直觀(guān)的。
getDay/setDay。該方法操作的是周數,序數從0開(kāi)始,即周日的值是0。
getMonth/setMonth。該方法操作的是月數沒(méi)有疑問(wèn),但是月數是從0開(kāi)始。
getFullYear/setFullYear。我通常建議用這組方法來(lái)代替直觀(guān)的getYear/setYear。
toDateString/toTimeString==輸出日期的方法。但是并不是那么的好用。
接下來(lái),讓我們一步一步來(lái)打造更適合自己的一套方法。
首先,我們來(lái)格式化輸出
var conf = {
syslang : "cn" //設置系統語(yǔ)言
};
Date.prototype.toFormatString = function(format) {
var weeks = {};
weeks['cn'] = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];
weeks['en'] = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
var self = this;
var fix = {
'yyyy':self.getFullYear(),
'MM':self.getMonth()+1,
'dd':self.getDate(),
'wk':weeks[conf.syslang][self.getDay()],
'hh':self.getHours(),
'min':self.getMinutes(),
'ss':self.getSeconds()
};
return format.replace(/[a-zA-Z]+/g,function(m){
return fix[m];
});
};
嗯,這個(gè)方法多了個(gè)全局的配置對象,但是這個(gè)不是必須的,只是在這里提示大家如果實(shí)現個(gè)性化定制,但是如果是自己的項目使用,我更建議減少代碼(把en或cn去掉)來(lái)打造適合自己項目的精簡(jiǎn)代碼。該方法的使用一目了然,在這里也不多解釋了。
接下來(lái)是日期的操作,第一組是日期的加減。熟悉.net的朋友都知道AddXXX的一組方法,因此我們也可以打造一組這樣的代碼,在此我只列舉一個(gè),有需要的可以自己實(shí)現其他的。其實(shí)這套方法可以使用偽泛型的方式將Add方法組并到一個(gè)方法。但是我更愿意用一目了然的方法名來(lái)提供。
Date.prototype.addMonth = function(n){
var month = this.getMonth();
this.setMonth(month+n);
};
怎么樣,很簡(jiǎn)單吧。不用擔心溢出(13月)或者負月份(-1月)會(huì )造成什么不良后果,日期對象會(huì )自己為了通過(guò)調整年數來(lái)得到合適的結果。
接下來(lái)是日期比較。純粹的日期比較不是問(wèn)題,因為getTime獲取毫秒數之后進(jìn)行加減操作即可。然而如果要是比較相差的天數怎么辦呢。其實(shí)也簡(jiǎn)單。那就是相差的毫秒數換算到天數即可
Date.prototype.compareTime = function(time) {
var ticks = time.getTime() - this.getTime();
return Math.floor(ticks/(1000*60*60*24));
}
至于比較周數同理,但是月數和年數呢?對不起,考慮到閏年和大小月等問(wèn)題,這個(gè)方法比較復雜,在這里就不貼出來(lái)了,如果您有興趣不妨嘗試著(zhù)自己寫(xiě)寫(xiě)看。
第一部分就到這里,下一篇將是正則表達式類(lèi)和全局對象方法。而自定義對象將在這些之后。預計這個(gè)禮拜會(huì )完成這幾篇。