JavaScript的数据类型

简单数据类型

  1. string
  2. number
  3. boolean
  4. function
  5. null
  6. undefined

复杂数据类型

  1. String
  2. Number
  3. Boolean
  4. Function
  5. Date
  6. Array
  7. RegExp
  8. Object

各种类型的深复制方式:

先来看看简单类型的复制方式:

//string
var s1 = 'abc';
var s2 = s1;
s2 = 'ccc';
console.log(s1); //number
var n1 = 12.1;
var n2 = n1;
n2 = 7410;
console.log(n1); //boolean
var b1 = true;
var b2 = b1;
b2 = false;
console.log(b1); //null
var nu1 = null;
var nu2 = nu1;
nu2 = 'abc';
console.log(nu1); //undefined
var u1 = undefined;
var u2 = u1;
u2 = 'abc';
console.log(u1);

从以上的代码可以看出,简单类型,只需要直接赋值就是深复制了。但是也有一个例外,那就是function。

接着来看看String、Number、Boolean、Date的深复制:

//String
var s1 = new String('s1');
var s2 = new String(s1);
console.log(s2); //Number
var n1 = new Number('1');
var n2 = new Number(n1);
console.log(n2); //Boolean
var b1 = new Boolean(1);
var b2 = new Boolean(b1);
console.log(b2); //Date
var d1 = new Date();
var d2 = new Date(d1);
console.log(d2);

除以上的做法之外,还需要对实例属性进行拷贝。那么剩下的Function、function、RegExp和Array还有Object又该怎么拷贝呢?这几个比较特殊,我们一个一个来:

对于Function和function的深拷贝,我们可以按照如下的方式来做:

var f1 = new Function('a', 'console.log("f1" + a);');
var f2 = function(b){console.log('f2' + b);}; //通过toString获取源代码(有浏览器兼容问题)
var code = f1.toString();
//利用eval进行复制
var f1_copy = (function(functionCode){
eval('var f = ' + functionCode);
return f;
})(code); f1_copy('abc'); //当然f2也可以用同样的方式来复制。

接着,我们来看下RegExp,可以同样同时eval来执行拷贝,也可以使用如下方式:

var reg1 = /abc/g;
var reg2 = new RegExp('abc', 'gmi'); var reg1_copy = (function(reg){
var pattern = reg.valueOf();
var flags = (pattern.global ? 'g' : '') +
(pattern.ignorecase ? 'i' : '') + (pattern.multiline ? 'm' : '');
return new RegExp(pattern.source, flags);
})(reg1);

最后,我们来说一说Array的复制,有的人可以说,直接用slice复制一份出来就是了,那我们来看看,是否真的达到效果的呢?

var o = {name: 'Jay'};
var arr1 = [o, '22', 1];
var arr2 = arr1.slice(0);
arr2[0].name = 'Arr2';
console.log(arr1[0].name);

很简短的代码,直接就把slice抛弃了,slice只能保证Array是新的,并不意味着内部的元素是深拷贝的,那么如何做呢?就是遍历元素,对每个元素进行深拷贝了。代码如下:

var o = {name: 'Jay'};
var arr1 = [o, '22', 1]; var arr2 = [];
for(var i = 0, len = arr1.length; i < len; i++){
//注意,deepClone还未实现
arr2.push(deepClone(arr1[i]));
}

以上对针对不同的类型,特殊的代码,那么如何来拷贝实例属性呢?代码如下:

var o = {p1: '1', p2: 2, p3: function(){}};

var copy = {};
for(var p in o){
//注意deepClone还未实现
copy[p] = deepClone(o[p]);
}

注意:针对复杂类型,还需要同时copy.constructor = source.constructor来保证构造函数一致。

最终的深复制代码

通过以上的分析与代码示例,那么我们最终的代码又是怎样的呢?详细代码如下:

//自调用函数,防御性编程
;
(function (window) {
'use strict'; function getCustomType(obj) {
var type = typeof obj,
resultType = 'object';
//简单类型
if (type !== 'object' || obj === null) {
resultType = 'simple';
} else if (obj instanceof String || obj instanceof Number || obj instanceof Boolean || obj instanceof Date) {
resultType = 'complex';
} else if (obj instanceof Function) {
resultType = 'function';
} else if (obj instanceof RegExp) {
resultType = 'regexp';
} else if (obj instanceof Array) {
resultType = 'array';
}
return resultType;
} function cloneProperties(dest, source) {
dest.constructor = source.constructor;
for (var p in source) {
dest[p] = deepClone(source[p]);
}
return dest;
} function cloneSimple(obj) {
return obj;
} function cloneComplex(obj) {
var result = new obj.constructor(obj);
return cloneProperties(result);
} function cloneFunction(obj) {
var funCopy = (function (f) {
eval('var abcdefg_$$$$ = ' + obj.toString());
return abcdefg_$$$$;
})(obj);
return cloneProperties(funCopy);
} function cloneRegExp(obj) {
var pattern = obj.valueOf();
var flags = (pattern.global ? 'g' : '') +
(pattern.ignorecase ? 'i' : '') + (pattern.multiline ? 'm' : '');
var reg = new RegExp(pattern.source, flags);
return cloneProperties(reg);
} function cloneArray(obj) {
var resultArr = [];
for (var i = 0, len = obj.length; i < len; i++) {
resultArr.push(deepClone(obj[i]));
}
for (var p in obj) {
if (typeof p === 'number' && p < len) {
continue;
}
resultArr[p] = deepClone(obj[p]);
}
return resultArr;
} function cloneObject(obj) {
var result = {};
result.constructor = obj.constructor;
for (var p in obj) {
result[p] = deepClone(obj[p]);
}
return result;
} function deepClone(obj) {
var f = undefined;
switch (getCustomType(obj)) {
case 'simple':
f = cloneSimple;
break;
case 'complex':
f = cloneComplex;
break;
case 'function':
f = cloneFunction;
break;
case 'regexp':
f = cloneRegExp;
break;
case 'array':
f = cloneArray;
break;
case 'object':
f = cloneObject;
break;
}
return f.call(undefined, obj);
} //挂载到window对象上
window.deepClone = deepClone;
})(window);

*:first-child {
margin-top: 0 !important;
}

body>*:last-child {
margin-bottom: 0 !important;
}

/* BLOCKS
=============================================================================*/

p, blockquote, ul, ol, dl, table, pre {
margin: 15px 0;
}

/* HEADERS
=============================================================================*/

h1, h2, h3, h4, h5, h6 {
margin: 20px 0 10px;
padding: 0;
font-weight: bold;
-webkit-font-smoothing: antialiased;
}

h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {
font-size: inherit;
}

h1 {
font-size: 28px;
color: #000;
}

h2 {
font-size: 24px;
border-bottom: 1px solid #ccc;
color: #000;
}

h3 {
font-size: 18px;
}

h4 {
font-size: 16px;
}

h5 {
font-size: 14px;
}

h6 {
color: #777;
font-size: 14px;
}

body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
margin-top: 0;
padding-top: 0;
}

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
margin-top: 0;
padding-top: 0;
}

h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {
margin-top: 10px;
}

/* LINKS
=============================================================================*/

a {
color: #4183C4;
text-decoration: none;
}

a:hover {
text-decoration: underline;
}

/* LISTS
=============================================================================*/

ul, ol {
padding-left: 30px;
}

ul li > :first-child,
ol li > :first-child,
ul li ul:first-of-type,
ol li ol:first-of-type,
ul li ol:first-of-type,
ol li ul:first-of-type {
margin-top: 0px;
}

ul ul, ul ol, ol ol, ol ul {
margin-bottom: 0;
}

dl {
padding: 0;
}

dl dt {
font-size: 14px;
font-weight: bold;
font-style: italic;
padding: 0;
margin: 15px 0 5px;
}

dl dt:first-child {
padding: 0;
}

dl dt>:first-child {
margin-top: 0px;
}

dl dt>:last-child {
margin-bottom: 0px;
}

dl dd {
margin: 0 0 15px;
padding: 0 15px;
}

dl dd>:first-child {
margin-top: 0px;
}

dl dd>:last-child {
margin-bottom: 0px;
}

/* CODE
=============================================================================*/

pre, code, tt {
font-size: 12px;
font-family: Consolas, "Liberation Mono", Courier, monospace;
}

code, tt {
margin: 0 0px;
padding: 0px 0px;
white-space: nowrap;
border: 1px solid #eaeaea;
background-color: #f8f8f8;
border-radius: 3px;
}

pre>code {
margin: 0;
padding: 0;
white-space: pre;
border: none;
background: transparent;
}

pre {
background-color: #f8f8f8;
border: 1px solid #ccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px;
}

pre code, pre tt {
background-color: transparent;
border: none;
}

kbd {
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
-moz-border-right-colors: none;
-moz-border-top-colors: none;
background-color: #DDDDDD;
background-image: linear-gradient(#F1F1F1, #DDDDDD);
background-repeat: repeat-x;
border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD;
border-image: none;
border-radius: 2px 2px 2px 2px;
border-style: solid;
border-width: 1px;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
line-height: 10px;
padding: 1px 4px;
}

/* QUOTES
=============================================================================*/

blockquote {
border-left: 4px solid #DDD;
padding: 0 15px;
color: #777;
}

blockquote>:first-child {
margin-top: 0px;
}

blockquote>:last-child {
margin-bottom: 0px;
}

/* HORIZONTAL RULES
=============================================================================*/

hr {
clear: both;
margin: 15px 0;
height: 0px;
overflow: hidden;
border: none;
background: transparent;
border-bottom: 4px solid #ddd;
padding: 0;
}

/* IMAGES
=============================================================================*/

img {
max-width: 100%
}
-->

JavaScript的深拷贝的实现的更多相关文章

  1. javascript对象深拷贝,浅拷贝 ,支持数组

    javascript对象深拷贝,浅拷贝 ,支持数组 经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One meth ...

  2. javascript浅拷贝深拷贝理解记录

    javascript的深拷贝和浅拷贝问题几乎是面试必问的问题.好记性不如烂笔头,特此来记录一下自己对深拷贝浅拷贝的理解. 顾名思义,拷贝就是copy复制,在js中可以浅而理解为对一个对象或者数组的复制 ...

  3. JavaScript实现深拷贝(深复制) 面试题

    1.两种方法实现深拷贝(深复制) (1)方法一:兼容性好,请仔细看代码(网上大部分代码有Bug) (2)方法二:需要对象满足JSON数据格式.JOSN数据格式:http://www.cnblogs.c ...

  4. JavaScript中深拷贝实现

    JavaScript 中深拷贝实现   拷贝时候涉及到: 1.循环结构 2.判断数组 Array 还是对象 Object   函数实现 /** * 获取满足条件的数组中的第一个元素 * @param ...

  5. 也来玩玩 javascript对象深拷贝,浅拷贝

    经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One method of copying an object is ...

  6. 【javascript】浅谈javaScript的深拷贝

        前言: 最开始意识到深拷贝的重要性是在我使用redux的时候(react + redux), redux的机制要求在reducer中必须返回一个新的对象,而不能对原来的对象做改动,事实上,当时 ...

  7. JavaScript之深拷贝和浅拷贝

    前言 工作中会经常遇到操作数组.对象的情况,你肯定会将原数组.对象进行‘备份’当真正对其操作时发现备份的也发生改变,此时你一脸懵逼,到时是为啥,不是已经备份了么,怎么备份的数组.对象也会发生变化.如果 ...

  8. javascript浅拷贝深拷贝详解

    一.浅拷贝 浅拷贝在现实中最常见的表现在赋值上面,例如 <!DOCTYPE html> <html lang="en"> <head> < ...

  9. 【javascript】详解javaScript的深拷贝

        前言: 最开始意识到深拷贝的重要性是在我使用redux的时候(react + redux), redux的机制要求在reducer中必须返回一个新的对象,而不能对原来的对象做改动,事实上,当时 ...

随机推荐

  1. vector的 emplace 和 insert 以及使用vector进行iterator遍历 且 erase的时候注意事项

    vector<int> first;//Size()==2 first.push_back(); first.push_back(); //first.insert(2); vector& ...

  2. C# 动态修改dll的签名 以及修改引用该dll文件的签名

    在读取RedisSessionStateProvider配置 提到用mono ceil 来修改程序集以及它的签名,里面GetPublicKey 和GetPubliKeyToken 方法里面那个字符串的 ...

  3. AutoCAD2007专业版

    07版的AutoCAD应该是一个很经典的版本了,点此下载,附带破解注册机和天正的插件包,可以查看天正软件画的图纸. AutoCAD2007本身没有标签工具,切换窗口很不方便,如果能配合多标签插件Doc ...

  4. 【转】升级Xcode6.3插件失效解决办法

     1.打开终端,输入以下代码获取到DVTPlugInCompatibilityUUID         defaults read /Applications/Xcode.app/Contents/I ...

  5. NGUI 减少drawcall规则

    前置说明一: Unity中的drawcall定义: 每次引擎准备数据并通知GPU的过程称为一次Draw Call. Unity(或者说基本所有图形引擎)生成一帧画面的处理过程大致可以这样简化描述:引擎 ...

  6. C#中将结构类型数据存储到二进制文件中方法

    以往在vb6,vc6中都有现成的方法将结构类型数据写入和读取到二进制文件中,但是在c#中却没有现成的方法来实现,因此我查阅了一些资料,借鉴了网上一些同学的做法,自己写了个类似的例子来读写结构类型数据到 ...

  7. Mysql自动备份工具1.0(2013年11月15日更新)

    Mysql自动备份工具1.0 下载地址 2013-11-15 1.解决日历控件在Windows7/8/8.1环境下遮挡按钮问题:2.解决按月备份当月没有该日期问题: 2013-11-13 1.Mysq ...

  8. Scala 深入浅出实战经典 第78讲:Type与Class实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...

  9. NCPC 2013: Dance Reconstruction

    题目大意 对一个初始矩阵进行置换操作,已知经K次置换后得到的矩阵为,求一组可能的. 样例解释 这里只选取第二组样例进行解释. 4 2 3 4 1 2 2 3 4 1 初始矩阵为,根据Sample Ou ...

  10. Transaction recovery: lock conflict caught and ignored

    Transaction recovery: lock conflict caught and ignored环境:RAC 4节点.oracle 11.2.0.4.redhat 5.9 64bit 问题 ...