Angular2中實現基於TypeScript的對象合併方法:extend()

TypeScript裏面沒有現成的合併對象的方法,這裏借鑑jQuery裏的$.extend()方法。寫了一個TypeScript的對象合併方法,使用方法和jQuery同樣。數組

部分代碼和jQuery代碼略有不一樣,主要是判斷元素是否爲 數組 和 純對象 的部分。jQuery中有方法可直接判斷元素是否爲數組($.isArray())和對象($.isPlainObject()),可是TpyeScript裏面沒有,這裏按照jQuery的實現寫了一下判斷,大部分狀況應該沒問題,但不保證適用全部狀況。感興趣的話能夠體會一下,遇到什麼問題一塊兒討論一下。this

 1   public class2type = {};
 2   ngOnInit() {
 3     this.getClass2type();
 4   }
 5  
 6   /**
 7    * 對象拷貝,參考$.extend()實現。首個參數爲true時爲深度拷貝,默認爲false。
 8    *
 9    * @param {any} args
10    * @returns
11    * @memberof SharedService
12    */
13   extend(...args) {
14     let options, name, src, srcType, copy, copyType, copyIsArray, clone,
15       target = args[0] || {},
16       i = 1,
17       length = args.length,
18       deep = false;
19      
20     if ( typeof target === 'boolean') {
21       deep = target;
22       target = args[i] || {};
23       i++;
24     }
25     if ( typeof target !== 'object' && typeof target !== 'function') {
26       target = {};
27     }
28     if ( i === length) {
29       target = this;
30       i--;
31     }
32     for ( ; i < length; i++ ) {
33       if ( (options = args[i]) !== null ) {
34         for ( name in options ) {
35           src = target[name];
36           copy = options[name];
37           // 若參數中字段的值就是目標參數,中止賦值,進行下一個字段的賦值
38           // 這是爲了防止無限的循環嵌套
39           if ( target === copy ) {
40             continue;
41           }
42           srcType = this.isArray(src) ? 'array': typeof src;
43           // 不能用typeof判斷一個數組是否爲數組格式,例:typeof [] -> object。如需判斷的話可用'[] instanceof Array'方法。
44           // copyType = typeof copy;
45           if ( deep && copy && ((copyIsArray = this.isArray(copy)) || typeof copy === 'object')) {
46             if ( copyIsArray ) {
47               copyIsArray = false;
48               clone = src && srcType === 'array' ? src : [];
49             } else {
50               clone = src && srcType === 'object' ? src: {};
51             }
52             target[name] = this.extend(deep, clone, copy);
53           } else if ( copy !== undefined ) {
54             target[name] = copy;
55           }
56         }
57       }
58     }
59     return target;
60   }
61  
62   public isArray = Array.isArray || function(obj) {
63     return this.type(obj) === 'array';
64   }
65  
66   private type(obj: object) {
67     if (obj === null) {
68       return obj + "";
69     }
70     return typeof obj === 'object' || typeof obj === 'function' ?
71         this.class2type[this.toString.call(obj)] || 'object' :
72         typeof obj;
73   }
74  
75   private getClass2type() {
76     'Boolean Number String Function Array Data RegExp Object Error'.split(' ').forEach(name => {
77       this.class2type['[object' + name + ']'] = name.toLowerCase();
78     });
79   }
80  
81   // 深度遍歷,使用方法:
82   let newObj = this.extend(true, {}, objA, objB);
相關文章
相關標籤/搜索