js详解实现数据的深拷贝(内含数据类型判断)

首先,要想实现数据的深拷贝就要明白什么是深拷贝。

        深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。


其次,实现深拷贝就要区分数据类型,因为对于对象来说,只是简单的赋值,共用的还是同一块内存,改变任何一个变量都会影响公用内存中的数据。

图1

1.所以就要判断数据的类型,数据类型分为基本数据类型和引用数据类型:

基本类型:String、Number、Boolean、Null、Undefined

引用类型:Object、Array、Date、Function、Error、RegExp、Math、Number、String、Boolean、Globle。

2.js有几种判断数据类型的方法,分别有type of,instanceof,constructor,Object.prototype.toString();

具体使用方法如下:

一、typeof,typeof有两种判断的方法 typeof A,typeof(A);

typeof 返回一个表示数据类型的字符串,返回结果包括:number、boolean、string、undefined、function、object等6种数据类型。

typeof 可以对JS基本数据类型做出准确的判断(除了null,typeof  null会返回object,因为特殊值null被认为是一个空的对象引用),而对于引用类型返回的基本上都是object, 当我们需要知道某个对象的具体类型时,typeof 就不能准确判断了。

图2

二、instanceof

判断对象和构造函数在原型链上是否有关系,如果有关系,返回真,否则返回假

图3

基本数据类型没有检测出他们的类型,但是我们使用下面的方式创建num、str、boolean,是可以检测出类型的:

图4

三、constructor:查看对象对应的构造函数

constructor 在其对应对象的原型下面,是自动生成的。当我们写一个构造函数的时候,程序会自动添加:构造函数名.prototype.constructor = 构造函数名


图5

从上面可以看到,undefined和null是不能够判断出类型的,并且会报错。因为null和undefined是无效的对象,因此是不会有constructor存在的

同时我们也需要注意到的是:使用constructor是不保险的,因为constructor属性是可以被修改的,会导致检测出的结果不正确。

四、Object.prototype.toString:不管是什么类型,可以立即判断出

toString是Object原型对象上的一个方法,该方法默认返回其调用者的具体类型,更严格的讲,是 toString运行时this指向的对象类型, 返回的类型

格式为[object xxx],xxx是具体的数据类型,其中包括:

String,Number,Boolean,Undefined,Null,Function,Date,Array,RegExp,Error,HTMLDocument,... 基本上所有对象的类型都可以通过这个方法获取到。

图6

从这个结果也可以看出,不管是什么类型的,Object.prototype.toString.call();都可以判断出其具体的类型。

下面是对toString的封装:

图7

五、综上,四种方法的优缺点如下

图8

从上表中我们看到了,instanceof和constructor不能跨iframe,上面没有细说,所以下面我们直接上例子喽

例:跨页面判断是否是数组

图9

从结果中可以看出,constructor和instanceof都没有正确的判断出类型,只有object.prototype.toString.call();正确判断出了

其实面试官也经常喜欢让说一种最简单的判断是数组的方法,记住喽是object.prototype.toString.call()哦!


最后,做了这么多的铺垫,该进入我们深拷贝的实现了

图10

此处对function进行的简单的赋值。


参考文章链接:https://blog.csdn.net/lhjuejiang/article/details/79623973

https://www.jb51.net/article/91105.htm

https://www.jb51.net/article/118551.htm

你可能感兴趣的:(js详解实现数据的深拷贝(内含数据类型判断))