Array 內建了很多方法,但是無法滿足所有使用者的需求,這時可以為 Array 物件擴充套件方法,以便提高程式碼重用率。擴充套件陣列的方法一般通過 Array 的原型來實現。
設計模式
Array.prototype._m = Array.prototype.m || (Array.prototype.m = function () {
//擴充套件方法的具體程式碼
});
Object.prototype.m = Array.prototype._m;
上面程式碼是一種陣列擴充套件方法的通用模式,詳細解析如下。
其中 Array 是陣列建構函式,prototype是建構函式的屬性,由於該屬性指向一個原型物件,然後通過點運算子為其定義屬性或方法,這些屬性和方法將被建構函式的所有範例物件繼承。
首先,利用判斷陣列中是否存在名稱為 m 的原型方法,如果存在則直接參照該原型方法即可,不再定義;否則,定義原型方法 m()。
其次,把定義的原型方法 m() 參照給原型方法 _m() ,這樣做的目的是防止原型方法 m() 參照給 Object 物件的原型時發生死迴圈呼叫,可以相容 Firefox 瀏覽器。
最後,把陣列的臨時原型方法 _m() 參照給 Object 物件的原型,這樣能夠確保所有物件都可以呼叫這個擴充套件方法。經過臨時原型方法 _m() 的中轉,就可以防止陣列(Array)和物件(Object)都定義了同名方法,如果把該方法傳遞給 Object,而 Objrct 的原型方法又參照了 Array 的同名原型方法,就會發生迴圈參照現象。
範例
為陣列擴充套件一個求所有元素和的方法。
Array.prototype._m = Array.prototype.sum || //檢測是否存在同名方法
(Array.prototype.m = function () { //定義該方法
var _n = 0, _this = []; //臨時匯總變數
for (var i in this) { //遍歷當前陣列物件
if (_this[i] = parseFloat(this[i])) _n += _this[i]; //如果陣列元素是數位,則進行累加
};
return _n; //返回累加的和
});
Object.prototype.sum = Array.prototype._sum; //把臨時方法賦值給物件的原型方法sum()
該原型方法 sum() 能夠計算當前陣列中元素為數位的和。在該方法的迴圈結構體中,首先試圖把每個元素轉換為浮點數,如果轉換成功,則把它們相加;轉換失敗將返回 NaN,會忽略該元素的值。
var a = [1,2,3,4,5,6,7,8,"9"]; //定義陣列直接量
console.log(a.sum()); //返回45
其中第 9 個元素是一個字串型別的數位,彙總時也被轉換為數值進行相加。