对象常用的方法和对象的拷贝

    xiaoxiao2022-07-07  195

    对象常用方法和对象拷贝

    对象方法浅拷贝深拷贝JSON.stringify/parse的方法递归的方法

    对象方法

    //Object.assign函数,第一个参数为目标对象,后面依次为源对象 //将来自一个或多个源对象中的值复制到一个目标对象 var first = {name : 'kong'}; var last = {age : 18}; var person = Object.assign(first, last); console.log(person); //{name : 'kong', age : 18},注意这里first因为是第一个参数会被当成目标对象,所以first自身属性也被更改为和person一样了,即first === person //用于克隆对象 var clone = Object.assign({}, person); //Object.freeze函数 //阻止修改现有属性的特性和值,并阻止添加新属性 var a = {name : 'kong', age : 18}; Object.freeze(a); //此时不允许添加或修改a的任何属性 //Object.is函数 //用于判断两个值是否相同 Object.is(a, b); //返回true或false //注意,该函数与==运算符不同,不会强制转换任何类型,应该更加类似于===,但值得注意的是它会将+0和-0视作不同值 //Object.keys函数 //用于返回对象可枚举的属性和方法的名称 var a = {name : 'kong', age : 18, func : function(){}}; Object.keys(a); //['name', 'age', 'func'] //Object.defineProperty函数 //将属性添加到对象,或修改现有属性的特性 var a = {}; Object.defineProperty(a, 'name', { value : 'kong', enumerable : true //该属性是否可枚举 }) //与之对应的是Object.defineProperties函数,可添加多个属性 Object.defineProperties(a, { name : { value : 'kong', enumerable : true }, job : { value : 'student', enumerable : true } }) //hasOwnProperty方法 //确定某个对象是否具有带指定名称的属性,有的话返回true,否则false //注意,该方法不会检查对象原型链中的属性 var s = new String('123'); console.log(s.hasOwnProperty('split')); //false console.log(String.prototype.hasOwnProperty('split')); //true //hasOwnProperty方法 //确定某个对象是否具有带指定名称的属性,有的话返回true,否则false //注意,该方法不会检查对象原型链中的属性 var s = new String('123'); console.log(s.hasOwnProperty('split')); //false console.log(String.prototype.hasOwnProperty('split')); //true //isPrototypeOf方法 //确定一个对象是否存在于另一个对象的原型链中 function a(){ } var b = new a(); console.log(a.prototype.isPrototypeOf(b)); //true

    浅拷贝

    浅拷贝的意思就是只复制引用(指针),而未复制真正的值。

    const originArray = [1,2,3,4,5]; const originObj = {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}}; const cloneArray = originArray; const cloneObj = originObj; console.log(cloneArray); // [1,2,3,4,5] console.log(originObj); // {a:'a',b:'b',c:Array[3],d:{dd:'dd'}} cloneArray.push(6); cloneObj.a = {aa:'aa'}; console.log(cloneArray); // [1,2,3,4,5,6] console.log(originArray); // [1,2,3,4,5,6] console.log(cloneObj); // {a:{aa:'aa'},b:'b',c:Array[3],d:{dd:'dd'}} console.log(originArray); // {a:{aa:'aa'},b:'b',c:Array[3],d:{dd:'dd'}}

    上面的代码是最简单的利用 = 赋值操作符实现了一个浅拷贝,可以很清楚的看到,随着 cloneArray 和 cloneObj 改变,originArray 和 originObj 也随着发生了变化。

    深拷贝

    JSON.stringify/parse的方法

    const originArray = [1,2,3,4,5]; const cloneArray = JSON.parse(JSON.stringify(originArray)); console.log(cloneArray === originArray); // false const originObj = {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}}; const cloneObj = JSON.parse(JSON.stringify(originObj)); console.log(cloneObj === originObj); // false cloneObj.a = 'aa'; cloneObj.c = [1,1,1]; cloneObj.d.dd = 'doubled'; console.log(cloneObj); // {a:'aa',b:'b',c:[1,1,1],d:{dd:'doubled'}}; console.log(originObj); // {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};

    确实是深拷贝,也很方便。但是,这个方法只能适用于一些简单的情况。比如下面这样的一个对象就不适用:

    const originObj = { name:'axuebin', sayHello:function(){ console.log('Hello World'); } } console.log(originObj); // {name: "axuebin", sayHello: ƒ} const cloneObj = JSON.parse(JSON.stringify(originObj)); console.log(cloneObj); // {name: "axuebin"}

    undefined、function、symbol 会在转换过程中被忽略,如果对象中含有一个函数时(很常见),就不能用这个方法进行深拷贝

    递归的方法

    就是对每一层的数据都实现一次 创建对象->对象赋值 的操作

    function deepClone(source){ const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象 for(let keys in source){ // 遍历目标 if(source.hasOwnProperty(keys)){ if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下 targetObj[keys] = source[keys].constructor === Array ? [] : {}; targetObj[keys] = deepClone(source[keys]); }else{ // 如果不是,就直接赋值 targetObj[keys] = source[keys]; } } } return targetObj; } const originObj = {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}}; const cloneObj = deepClone(originObj); console.log(cloneObj === originObj); // false cloneObj.a = 'aa'; cloneObj.c = [1,1,1]; cloneObj.d.dd = 'doubled'; console.log(cloneObj); // {a:'aa',b:'b',c:[1,1,1],d:{dd:'doubled'}}; console.log(originObj); // {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}}; const originObj = { name:'axuebin', sayHello:function(){ console.log('Hello World'); } } console.log(originObj); // {name: "axuebin", sayHello: ƒ} const cloneObj = deepClone(originObj); console.log(cloneObj); // {name: "axuebin", sayHello: ƒ}
    最新回复(0)