Angular2中实现基于TypeScript的对象合并方法:extend()
TypeScript里面没有现成的合并对象的方法,这里借鉴jQuery里的$.extend()方法。写了一个TypeScript的对象合并方法,使用方法和jQuery一样。
部分代码和jQuery代码略有不同,主要是判断元素是否为 数组 和 纯对象 的部分。jQuery中有方法可直接判断元素是否为数组($.isArray())和对象($.isPlainObject()),但是TpyeScript里面没有,这里按照jQuery的实现写了一下判断,大部分情况应该没问题,但不保证适用所有情况。感兴趣的话可以体会一下,遇到什么问题一起讨论一下。
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);