JS数组与对象的合并

Js数组与对象的合并、深拷贝、对象类型的判断

数组合并

  1. concat方法

    1
    2
    3
    4
    var a=[1,2,3],b=[4,5,6];
    var c=a.concat(b);
    console.log(c);// 1,2,3,4,5,6
    console.log(a);// 1,2,3 不改变本身
  2. 循环遍历

    1
    2
    3
    4
    5
    6
    7
    8
    var arr1=['a','b'];
    var arr2=['c','d','e'];
    for(var i=0;i<arr2.length;i++){
    arr1.push(arr2[i])
    }
    console.log(arr1);//['a','b','c','d','e']
  3. apply

    1
    2
    3
    4
    5
    6
    var arr1=['a','b'];
    var arr2=['c','d','e'];
    Array.prototype.push.apply(arr1,arr2);
    //或者
    arr1.push.apply(arr1,arr2);<br>console.log(arr1) //['a','b','c','d','e']

对象的合并

  1. $.extend()

    1
    2
    3
    4
    5
    6
    var obj1= {'a': 1};
    var obj2= {'b': 1};
    var c = $.extend(obj1, obj2);
    console.log(obj1); // {a: 1, b: 1} obj1已被修改
    //或者 <br>var obj3 = $.extend({}, obj1, obj2) <br>console.log(obj3); //{a: 1, b: 1} 不会改变obj1,obj2
  2. 遍历赋值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var obj1={'a':1};
    var obj2={'b':2,'c':3};
    for(var key in obj2){
    if(obj2.hasOwnProperty(key)===true){ <br> //此处hasOwnProperty是判断自有属性,使用 for in 循环遍历对象的属性时,原型链上的所有属性都将被访问会避免原型对象扩展带来的干扰
    obj1[key]=obj2[key];
    }
    }
    console.log(obj1);//{'a':1,'b':2,'c':3};
  3. Obj.assign()
    Object.assign(target, …sources)
    assign后来的源的属性会覆盖早先的源的属性
    assign不是深拷贝,如果源对象的属性是一个指向对象的引用,他会只拷贝那个引用值(如下)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    let obj1 = { a: 0 , b: { c: 0}};
    let obj2 = Object.assign({}, obj1);
    console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}
    obj1.a = 1;
    console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
    console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}
    obj2.a = 2;
    console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
    console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 0}}
    obj2.b.c = 3;
    console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}}
    console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 3}}
    // Deep Clone
    obj1 = { a: 0 , b: { c: 0}};
    let obj3 = JSON.parse(JSON.stringify(obj1));
    obj1.a = 4;
    obj1.b.c = 4;
    console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}}

另外assign会覆盖原对象

1
2
3
4
5
6
7
var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };
var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1); // { a: 1, b: 2, c: 3 }, 注意目标对象自身也会改变。

深拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var cloneObj = function(obj){
var str, newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
} else if(window.JSON){
str = JSON.stringify(obj), //将对象化为字符串
newobj = JSON.parse(str); //还原
} else {
for(var i in obj){
newobj[i] = typeof obj[i] === 'object' ?
cloneObj(obj[i]) : obj[i];
}
}
return newobj;
};

对象类型的判断

  1. typeof
    形如 var x = “xx”; typeof x == ‘string’ typeof(x);
    返回类型有:’undefined’ “string” ‘number’ ‘boolean’ ‘function’ ‘object’
    缺点:对于object类型不能细分是什么类型
    优点:对空null的判断 ‘undefined’的应用

  2. instanceof
    形如 var d = new String(‘test’); d instanceof String ==true;
    返回的类型有:String Number Boolean Function Object Array Date
    优点:能区分出更细的类型如 Date Array 如 var num = 3; num instanceof Number 能返回具体的类型
    缺点:直变量不能区分 必须采用new 的对象

  3. constructor
    形如:var x = []; x.constructor==Array;
    优点:可以返回继承的类型
    缺点: 不能对象的细分,如继承 必须手动修正

  4. Object.prototype.toString.call();
    优点:通用,返回”[objectString]” 具体object的类型
    缺点:不能返回继承的类型

一般先typeof如果返回object再constructor