JavaScript 浅拷贝和深拷贝

1、JavaScript数据类型

基本数据类型

string、number、null、undefined、boolean、symbol(ES6新增) 变量值存放在栈内存中,可直接访问和修改变量的值赋值的时候深拷贝

typeof可以返回其基本数据类型,但是NULL类型会返回object,因此null值表示一个空对象指针

引用类型

Object、Function、Array、RegExp、Math、Date是对象类型,存放在堆内存中,赋值的时候浅拷贝
在栈内存中变量保存的是一个指针,指向对应在堆内存中的地址。
当访问引用类型的时候,要先从栈中取出该对象的地址指针,然后再从堆内存中取得所需的数据

引用数据类型使用typeof会返回object

 2、浅拷贝实例

var a = [1,2,3,4];
var b = a;
a[0] = 0;
console.log(a,b);//输出都是0,2,3,4

3、JSON内置对象深拷贝

 可处理一般的对象进行深拷贝,但是不能处理函数、正则等对象

JSON 对象是ES5中引入的新的类型,JSON对象parse方法可以将JSON字符串反序列化成JS对象,stringify方法可以将JS对象序列化成JSON字符串

var a = {age:1,name:'ccy',info:{address:'wuhan',interest:'playCards'}};
var b = JSON.parse(JSON.stringify(a));
a.info.address = 'shenzhen';
console.log(a.info,b.info);

4、自定义深拷贝函数

/**
 * 深克隆
 * @param Origin 克隆的是哪一个对象
 * @param Target 克隆给谁,可以为空,不传,会返回
 * @returns {Target} 
 */
export function deepClone(Origin, Target) {
  var Target = Target || {};
  for (var prop in Origin)
  {
    if (Origin.hasOwnProperty(prop)) {//如果返回false则说明为原型上的属性,不用拷贝
      if (Origin[prop] !== 'null' && typeof (Origin[prop]) === 'object')//引用类型,进行递归调用
      {
        if (Object.prototype.toString.call(Origin[prop]) === '[object Array]') {
          Target[prop] = [];
        } else {
          Target[prop] = {};
        }
        deepClone(Origin[prop], Target[prop]);//递归
      }
      else {
        Target[prop] = Origin[prop];//直至属性为基本类型进行赋值
      }
    }
  }
  return Target;
}

注意:如果遇到对象的属性存在相互引用的话,会出现死循环的情况。

 

最后附上JavaScript数据类型判断方法

object.prototype.toString.call() 方法可以精确的判断js对象的数据类型:[object 对象数据类型] 

Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(“abc”);// "[object String]"
Object.prototype.toString.call(123);// "[object Number]"
Object.prototype.toString.call(true);// "[object Boolean]"
**函数类型**
Function fn(){
  console.log(“test”);
}
Object.prototype.toString.call(fn); // "[object Function]"
**日期类型**
var date = new Date();
Object.prototype.toString.call(date); // "[object Date]"
**数组类型**
var arr = [1,2,3];
Object.prototype.toString.call(arr); // "[object Array]"
**正则表达式**
var reg = /[hbc]at/gi;
Object.prototype.toString.call(reg); // "[object RegExp]"

typeof只能区分基本类型,即:numberstringundefinedbooleanobject

对于nullarrayfunctionobject来说,使用typeof都会统一返回object字符串

 

posted @ 2020-10-27 13:53  JackGIS  阅读(123)  评论(0编辑  收藏  举报