TypeScript里面没有现成的合并对象的方法,这里借鉴jQuery里的$.extend()方法。写了一个TypeScript的对象合并方法,使用方法和jQuery一样。
部分代码和jQuery代码略有不同,主要是判断元素是否为
数组
和
纯对象
的部分。jQuery中有方法可直接判断元素是否为数组($.isArray())和对象($.isPlainObject()),但是TpyeScript里面没有,这里按照jQuery的实现写了一下判断,大部分情况应该没问题,但不保证适用所有情况。感兴趣的话可以体会一下,遇到什么问题一起讨论一下。
1 public class2type = {};
2 ngOnInit() {
3 this.getClass2type();
6 /**
7 * 对象拷贝,参考$.extend()实现。首个参数为true时为深度拷贝,默认为false。
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;
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 }
62 public isArray = Array.isArray || function(obj) {
63 return this.type(obj) === 'array';
64 }
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 }
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 }
81 // 深度遍历,使用方法:
82 let newObj = this.extend(true, {}, objA, objB);