在對象的原型上添加方法?

HTML5學堂:利利前段時間寫了幾個數組、字符串的方法,其中有一個是克隆(複製)一個數組。因而,最近一直在琢磨如何讓這個複製變得更簡單,可不能夠把這個自定義的方法掛載在原型上呢?研究了幾天,也算是得出一些基本的結論。本文除了討論「在對象的原型上添加方法」好仍是壞以外,也會爲你們分享一個乾貨,是利利本身寫的「複製」變量的方法。一塊兒來看吧~!前端


本文主要內容

1 「複製」/「克隆」數組的功能需求web

2 在對象的原型上添加方法是否合理?數組

3 「複製」各種變量的功能封裝瀏覽器


「複製」/「克隆」數組的功能需求

最初的代碼

剛開始的時候拿到這個需求,第一反應是用for循環,因而乎本身寫出了以下的代碼:微信

  1. var arr = ["HTML5學堂", "利利", "堡堡"];函數

  2. var newArr = [];優化

  3. for (var i = 0; i < arr.length; i++) {this

  4.     newArr[i] = arr[i];spa

  5. };.net

額外提醒:可能有前端小夥伴考慮說直接var newArr = oldArr;豈不是更好,此處各位須要注意數組屬於引用類型變量,這種書寫方式是將oldArr的地址賦值給了newArr。oldArr和newArr指向同一個數組。

關於「引用類型變量與值類型變量」,若是不是太清楚的童鞋能夠點擊——>《引用類型變量的那個坑》查看


優化克隆功能

左看右看,總以爲for循環太複雜了,回顧數組的各種方法,忽然想到了concat方法。concat方法的功能是基於當前數組中的全部項建立一個新數組,返回新數組。該方法會先建立一個當前數組的副本,而後將接收到的參數,添加到這個副本末尾,最後返回新構建的數組。當咱們沒有給concat方法傳遞參數時:複製當前數組並返回副本。

因而乎,功能代碼就變成了這個樣紙~~~

  1. var arr = ["HTML5學堂", "利利", "堡堡"];

  2. function clone(val) {

  3.     return val.concat();

  4. }

  5. var newArr = clone(arr);


問題來了

實現了,可是要面臨的問題來了,既然該方法可以實現,那麼若是爲了方便,我是否是能夠爲全部的數組元素都增長這個方法,將這個方法掛載到Array的原型上,即:

  1. var arr = ["HTML5學堂", "利利", "堡堡"];

  2. Array.prototype.clone = function() {

  3.     return this.concat();

  4. }

  5. 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原生方法,返回的對象是沒法繼承數組的任何方法的,因此就會報錯。


「複製」各種變量的功能封裝

雖然放棄了將變量「複製」的功能放在原型上,可是依舊打算對這個功能進行一些擴展,封裝一個可以克隆數字、字符串、數組、對象等多種數據的功能函數,豈不是更好?因而乎~~~

  1. var arr = ["HTML5學堂", "利利", "堡堡"];

  2. function clone(targetObj) {

  3.     if (targetObj instanceof Array) {

  4.         return targetObj.concat();

  5.     } else if (targetObj instanceof Object) {

  6.         var newObj = {};

  7.         for (var i in targetObj) {

  8.             newObj[i] = targetObj[i];

  9.         };

  10.         return newObj;

  11.     } else {

  12.         return targetObj;

  13.     }

  14. }

  15. var result = clone(arr);

  16. console.log(result);

HTML5小編-利利 耗時3h

歡迎溝通交流~HTML5學堂


HTML5學堂技術交流羣

長按二維碼



本文分享自微信公衆號 - HTML5 WEB前端分享(h5course-com)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索