Skip to content

什么是深拷贝和浅拷贝 #1

Description

@nokelong

一、概念
1、浅拷贝
对于字符串类型,浅复制是对值的复制;对于引用类型(Objeact, Array 等)只拷贝指向对象的指针,没有复制对象本身,新旧对象使用同一个内存地址。
2、深拷贝
复制对象本身,新旧对象内存地址隔离,修改新对象不影响久对象。

二、实现
1)浅拷贝实现
浅拷贝实现主要包括三种方式遍历、Object.assgin、拓展运算符...
1、遍历方式

function extend(soruce) {
   var dist = {};
   for(var props in soruce) {
       if(soruce.hasOwnProperty(props)) {
          dist[props]  = soruce[props]
        }
     }
     return dist;
}

2、Object.assgin方式

let obj = {
    name: "tomcat",
    age: 2
}
let target = Object.assgin({}, obj);
console.log(target);

3、使用拓展运算...

var obj = {
  name: "tom",
  age: 18,
  sayhi() {
     console.log('hi')
  },
}
var newObj = {...obj}
console.log(newObj);

2)深拷贝实现
深拷贝实现基本2种方式,遍历和利用JSON.parse。
1、JSON.parse只支持Number, String, Boolean, Array, 扁平对象,不支持RegExp;改造了对象的contructor为object。

function deepClone(obj) {
    var target= {};
    try {
        target= JSON.parse(JSON.stringify(obj));
    }
    return target;
}

2、遍历对象

function deepClone(obj) {
  var target;
  if(typeof obj === 'object') {
    target = Array.isArray(obj) ? [] : {};
    for(var key in obj) {
      target[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key]
    }
  } else {
    target = obj;
  }
  return target;
}

另外一种实现

function extend(source, isDeep) {
	
	var isObjFun = function (name) {
		var toString = Object.prototype.toString;
		return function (){
			return toString.call(arguments[0]) === '[object ' + name + ']'
		}
	}
    var isObject = isObjFun('Object'),
        isArray = isObjFun('Array'),
        isBoolean = isObjFun('Boolean'),
        isFunction = isObjFun('Function');

	function _extend(source) {
        if (source === null || typeof source != 'object' && !isFunction(source)) {
        	return source;
        } 
        if (isFunction(source)){
            return new Function('return ' + source.toString())()
        } else {
            var  value , target = isArray(source) ? []: {};
             for(var prop in source) {
                value = source[prop];
                if (value == source) {
                	continue;
                }
                if (isDeep) {  //是否是深拷贝
                    if (isArray(value) || isObject(value)) {
                        target[prop] = extend(value, isDeep);
                    } else if(isFunction(prop)) {
                        target[prop] =new Function('return '+ value.toString())();
                    }
                } else {
                	target[prop]  = value
                }
         	}
         	return target;
            }
	}

	return _extend(source);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions