HTML5學堂:利利前段時間寫了幾個數組、字符串的方法,其中有一個是克隆(複製)一個數組。因而,最近一直在琢磨如何讓這個複製變得更簡單,可不能夠把這個自定義的方法掛載在原型上呢?研究了幾天,也算是得出一些基本的結論。本文除了討論「在對象的原型上添加方法」好仍是壞以外,也會爲你們分享一個乾貨,是利利本身寫的「複製」變量的方法。一塊兒來看吧~!前端
本文主要內容
1 「複製」/「克隆」數組的功能需求web
2 在對象的原型上添加方法是否合理?數組
3 「複製」各種變量的功能封裝瀏覽器
「複製」/「克隆」數組的功能需求
最初的代碼
剛開始的時候拿到這個需求,第一反應是用for循環,因而乎本身寫出了以下的代碼:微信
var arr = ["HTML5學堂", "利利", "堡堡"];函數
var newArr = [];優化
for (var i = 0; i < arr.length; i++) {this
newArr[i] = arr[i];spa
};.net
額外提醒:可能有前端小夥伴考慮說直接var newArr = oldArr;豈不是更好,此處各位須要注意數組屬於引用類型變量,這種書寫方式是將oldArr的地址賦值給了newArr。oldArr和newArr指向同一個數組。
關於「引用類型變量與值類型變量」,若是不是太清楚的童鞋能夠點擊——>《引用類型變量的那個坑》查看
優化克隆功能
左看右看,總以爲for循環太複雜了,回顧數組的各種方法,忽然想到了concat方法。concat方法的功能是基於當前數組中的全部項建立一個新數組,返回新數組。該方法會先建立一個當前數組的副本,而後將接收到的參數,添加到這個副本末尾,最後返回新構建的數組。當咱們沒有給concat方法傳遞參數時:複製當前數組並返回副本。
因而乎,功能代碼就變成了這個樣紙~~~
var arr = ["HTML5學堂", "利利", "堡堡"];
function clone(val) {
return val.concat();
}
var newArr = clone(arr);
問題來了
實現了,可是要面臨的問題來了,既然該方法可以實現,那麼若是爲了方便,我是否是能夠爲全部的數組元素都增長這個方法,將這個方法掛載到Array的原型上,即:
var arr = ["HTML5學堂", "利利", "堡堡"];
Array.prototype.clone = function() {
return this.concat();
}
var newArr = arr.clone();
這樣掛載到原型上,的確方便了咱們的調用和開發,可是真的好麼?
在對象的原型上添加方法是否合理?
仔細思考以後,並查閱了一些相關資料,利利最終仍是放棄了將方法添加到對象的原型上,爲何呢?
1 防止衝突
咱們能夠想象,若是僅僅由咱們一我的開發項目時,是不會出現什麼衝突問題的,可是,若是參與項目的人不止一個,那麼我在對象上定義一個方法,別人是否是也能夠在對象上定義一個方法呢?此時,很容易出現衝突,而且,一旦形成衝突,以後就須要爲了解決這個衝突而花費更多的時間,得不償失。
2 不易定位錯誤位置
咱們本身書寫的代碼,有時可能會有一些考慮不周,必然會產生或多或少的bug,若是這些方法是正常存在於window的全局做用域下,也能夠經過JS文件尋找到相應內容時,那麼,咱們就能夠比較快速的進行錯誤定位(採用註釋法、斷點調試、console命令等)。可是,當方法掛載在了原型上時,咱們可能就很難發現問題的所在。簡言之就是:出現Bug時,不容易進行問題的定位。
3 防止代碼向上不兼容
關於這一條,查閱了比較多的信息,特別是getElementsByClassName~
所謂代碼向上不兼容,指的是:咱們定義了一個Array.prototype.clone,在當前的ECMAScript5.0(6.0)當中並無這個方法,可是頗有可能在ECMAScript7.0甚至更高版本當中出現這個方法,一旦出現這個方法,那麼咱們原有的代碼就須要進行相關的修改。
額外擴展知識:當時實現document.getElementsByClassName,直接使用了document.prototype並返回了一個數組的實例(prototype返回的是Array)。可是DOM 後來原生方法裏對這個方法返回的是一個Nodelist實例,結果就是以前用了Prototype庫的代碼,運行在新瀏覽器的時候,用的是DOM原生方法,返回的對象是沒法繼承數組的任何方法的,因此就會報錯。
「複製」各種變量的功能封裝
雖然放棄了將變量「複製」的功能放在原型上,可是依舊打算對這個功能進行一些擴展,封裝一個可以克隆數字、字符串、數組、對象等多種數據的功能函數,豈不是更好?因而乎~~~
var arr = ["HTML5學堂", "利利", "堡堡"];
function clone(targetObj) {
if (targetObj instanceof Array) {
return targetObj.concat();
} else if (targetObj instanceof Object) {
var newObj = {};
for (var i in targetObj) {
newObj[i] = targetObj[i];
};
return newObj;
} else {
return targetObj;
}
}
var result = clone(arr);
console.log(result);
HTML5小編-利利 耗時3h
歡迎溝通交流~HTML5學堂
HTML5學堂技術交流羣
(長按二維碼)
本文分享自微信公衆號 - HTML5 WEB前端分享(h5course-com)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。