一、 類與對象
在 JavaScript 世界裡,關於物件導向第一個要澄清的概念就是類。對象都是有類來定義的,通過類來建立對象就是我們所熟悉的執行個體化。然而,在 JavaScript 中別沒有真正的類,對象的定義就是對象自身。而 ECMA-262 乾脆把這種妥協的方式稱作為對象的調和劑。為了方便理解,我通常把這個發揮類的作用的調和劑稱為類。
二、 內建對象
1、 Array類
數組在 js 中是非常常用的一種資料結構,由於其靈活性和易用性,合理的使用數組可以協助我們更好的實現相應的功能。
讓我們先看 Array 對象的建立吧
第一種:
- var arr = new Array(10);
該方法在實際的使用當中並不那麼的實用,與很多編譯型語言不同, js 數組的長度是可變的,不但增強了靈活性,還給我們有了更多好的選擇。
第二種:
- var arr = new Array("one","two","three");
使用 new 方式建立數組的方法一般多為這兩者,當然也可以使用 new Array() 建立一個空的數組對象。通常情況下,我推薦如下的方法
第三種:
- var arr = ["one","two","three"];
使用數組的字面量方式建立一個數組對象,不但簡潔易讀,而且幾乎完全等價於使用 new 方式建立數組對象的效果。數組對象有很多好用的方法,接下來我們就一起看看這個數組對象的強大功能吧。
首先要介紹的是 push 方法,學過資料結構的朋友都知道 push 意味著什麼,沒錯,他的出現讓數組能夠實現棧的資料結構(同時需要配合 pop 方法)。 push 方法協助我們緊湊的添加數組元素。前面提到js中的數組是長度是可變的,則我們可以添加元素。既然可以通過 arr[length] = newValue; 來給 arr 添加一個新元素並放置於數組尾。更好的辦法就是使用 push 方法。 arr.push(newValue); 怎麼樣,使用他比你還要通過數組長度來賦新值方便多了吧。在這裡有一點需要注意。請看下面的代碼:
- var arr = [];
- arr[4] = 5;
- alert(arr.length == 5);
- alert(arr); //alert : ,,,,5
當我們需要給指定數組位置賦予指定的值的時候,這種賦值就顯得十分有用了,比如在用於裝箱排序的時候。
pop 方法則是實現與 push 相反的作用,返回數組的最後一個元素,並出棧。
- var arr = [1,2,3,4,5];
- var ele = arr.pop();
- alert(ele == 5);
- alert(arr.length == 4);
數組對象的 toString 和 valueOf 方法比較人性化的重寫了,它的實現是把每一項都調用 toString 方法,然後用半形逗號(,)串連每一項。那麼:
- var arr = [1,2,3,4,5];
- alert(arr);//output:1,2,3,4,5
toLocaleString 方法在這裡不做詳細說明了,他的效果與 toString 方法類似,只是每項調用 toLocateString 方法。
如果你想使用個人化的分隔字元來顯示數組元素,那麼 join 方法可能會更加的適合。比如:
- var city = ["上海","北京","天津","重慶","深圳"];
- alert(city.join(""));//output:上海北京天津重慶深圳
由此可見 join 是把數組元素轉換為一個字串。在介紹字串的時候我們將再次看到 join 方法的使用。
concat 方法和 slice 方法是又一對好用的方法,這兩個方法的特殊之處在於 String 對象也擁有他們。當我們希望給一個數組添加多個數組元素的時候,使用 push 可能就顯得有些冗餘和複雜了,而且也會讓 coding 變得不那麼有意思了。好在我們有 concat 方法,該方法將其參數們按序加入數組元素中。如:
- var arr = [1,2,3,4,5];
- arr = arr.concat(6,7,8,9);
- alert(arr.length == 9);
注意, concat 並不修改數組對象本身,而是將數組元素與 concat 方法的數組元素合并後返回。所以需要給數組元素進行賦值運算才行。
slice 方法則是從數組對象中返回一個子數組。該子數組是從 slice 方法的第一個參數所指位置至第二個參數所指的位置。這是一個半開半閉區間 [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 方法一樣不是修改數組對象本身。同時參數1,3表示從位置1到位置3的半開半閉區間的子數組。
剛才討論了後進先出的棧操作,現在我們來看看先進先出的隊列操作吧。進列使用 push 方法沒有問題,那麼出列呢。是 shift ,他刪除數組對象的第一個元素並返回:
- var arr = [1,2,3,4,5];
- var ele = arr.shift();
- alert(ele); //output:1
- alert(arr.length);//output:4
另外一個還有一個方法,叫 unshift ,他將新元素插入數組對象的第一項,究其功能與 shift 是相反的操作。
sort 方法很靈活,使用好了,他可以給數組元素以任意你想要的排序方式來進行排序。因為 sort 方法接收一個匿名函數(其實,它同樣可以接收一個非匿名的函數,但是通常不推薦為此而建立一個這樣的命名函數,除非該函數可重用)作為自己的排序的條件。比如:
- 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 方法,他的左右就是將對象遍曆使之可以輸出為索引值對格式字串,在介紹原型鏈的時候會再次提到。我們可以看到 sort 方法通過這個匿名方法讓我們可以根據 key 屬性來進行排序。那就讓我們來看看這個匿名方法吧。
- function(a,b) {
- return a.key - b.key;
- };
可以看到,這個方法接收2個參數,然後對參數的自身或某個屬性進行比較,然後返回比較結果,他們的比較結果與排序對應關係如下:
如果 paramA - paramB > 0,return 正數 ,則 b 排在 a 的前面
如果 paramA - paramB < 0,return 負數 ,則 b 排在 a 的後面
如果 paramA - paramB = 0,return 0 ,則順序不變。
上面的實現是順序排序,那麼 倒序 呢?對, return paramB - paramA;
reverse 方法可以將數組對象反轉。他和 sort 方法一樣是修改數組對象內部元素順序的。
最後我們看看 splice 方法,他是替換和刪除數組對象元素的方法。根據參數的改變而擁有不同的實現結果。 splice(pos,count[,insertParams]);pos 參數是刪除元素的第一個項的位置, count 參數是刪除元素的個數,當為0時則不刪除(不刪除還要這個方法幹嘛,別著急,往下看), insertParams 則是參數列表,這些參數是即將插入的元素集合。插入的位置為 pos 。那麼就出現了以下幾種情況了。
1、 insertParams 忽略時,該方法就是刪除數組元素
2、 當 count 參數為0時,該方法將只是將 insertParams 插入到 pos 位置
3、 當 count 參數不為0且 insertParams 不忽略時,該方法就是刪除 pos 位置開始的 count 個元素,並替換 insertParams 參數集合。
2、 Math類
我們花了很大的篇幅來介紹數組類,我要再次強調一點,這個類只是為了介紹方便強加於它的一個名字,實際上他們也只是對象。而非真正的類。
Math 類的使用範圍相對狹窄,因為他作為一個數學計算的類,而非一個資料結構類,但是我們也看到了 Math.random 以及各種取整等常用方法。因此我們不妨花些時間來看看他們,但是如果你對此興趣不大,那麼看完 random 方法之後就可以跳到下一節去,以後用到的時候再翻手冊就可以了。
Math 通常是一個“靜態”類,因為沒有人會執行個體化一個 Math 對象,而是直接使用其“靜態”方法,有些資料直接稱它為 Math 對象,在這裡我們不妨稱它為“靜態”類吧。
首先我必須介紹 random 方法,因為他常用且太有用了。在製造隨機事件的時候他總是不可或缺,同樣在防止緩衝上他也顯得很有用處。 Math.random 方法返回的是一個 0到1 之間的開區間浮點數,即 (0,1) ,他的使用非常簡單,唯一需要注意的是,當我們取整的時候對 floor 和 ceil 方法的篩選時需要謹慎,前者使得 random 間接轉換為前閉後開區間,而後者則是前開後閉區間。假如我們現在需要一個取1-100的隨機數,那麼有如下的兩種常用解決方案
方法一:
- Math.ceil(Math.random*100);
方法二:
- Math.floor(Math.random*100)+1;
ceil 方法和 floor 方法都是用來取整的數學方法,根據單詞含義我們可以理解,前者是向上取整,而後者則是向下取整。
當我們從一個連續的數組對象中隨機播放一個數組元素時,我們可以藉助 random 輕鬆的來幫我們挑選:
- ["ipad","iphone","ipod touch","ipod nano","macbook"]
- [Math.ceil(Math.random()*4)];
這個例子中,我直接使用的是數組字面量,一開始你可能會覺得費解或者不易理解,當你深入以後你會發現原來 JavaScript 是如此的方便、簡潔、靈活。
前面我們介紹了 ceil 和 floor 方法的取整,那麼當我們想要接近舍入時呢,我們可以使用 Math.round 方法,他在取整時根據數值進行靠近取整。比如 Math.round(5.4) 返回的是 5 。那麼如果 Math.round(5.5) 呢,答案是 6 而不是 5 。關於這點需要有所瞭解。好吧我承認我較真了,但是知道了他有什麼壞處呢。
當我們想從 2 個數中取得較小或者較大的數的時候怎麼做呢?
- if(a>b) {
- return a;
- } else {
- return b;
- }
我們多慮了。 Math 提供了 Math.max 和 Math.min 方法來協助我們解決這個問題。
Math 還有一大堆的“靜態”方法和屬性。在這裡我就不一一列舉了,當我們要進行數學計算的時候不妨去查查手冊。
3、 String類
字串對象的使用頻率恐怕比數組對象有過之而無不及,為什麼我要放到後面來說呢,其實是因為對於字串,我們要說的更多,而可擴充的方法和工具函數也更加豐富。我們一起先來看看 String 類本身吧。
建立一個字串對象有以下幾種方法:
方法一:
- var str = new String("Hello World");
方法二:
- var str = String("Hello World");
方法三:
- var str = "Hello World";
和數組對象一樣,我推薦大家使用最後一種方法,及字串字面量。關於是否有 new 的區別,周愛民老師的部落格中有過很詳細的解釋,同時,如果你一直讀下去,在介紹自訂對象的時候也會提到 new 運算子。
String 對象有且只有一個屬性 length ,他返回字串的長度,在這裡我們必須要弄明白 JavaScript 是 unicode 編碼,那麼漢字和英文都當作一個字元長度來處理,之所以提到這個是因為曾經遇到不止一位朋友在論壇提問這個問題,呵呵,動手的必要性啊。那麼如果我們非要把漢字當作 2 個字元長度來計算呢?這就帶來了我們第一個自訂方法。
- String.prototype.getLength = function(isSplit){
- if(isSplit) {
- return this.replace(/[^\u0000-\u00FF]/g,"tt").length;
- }
- else {
- return this.length;
- }
- };
該方法通過傳遞一個 Boolean 類型的參數,如果為真則將非半形字元、數字、英文字母分割為 2 個長度來求長度,不用擔心這個分割,他並不會修改字串對象本身。如果為假,則直接返回 length 屬性值。由於介紹方法不是根據方法的字元排列順序而來,如果作為字典,我想還是 w3school 更合適,因為我是根據作用的不同和關聯性來進行介紹。 ok ,介紹完了 length 屬性,我們看看字串尋找吧。
[1] [2] 下一頁