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