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. 教程:使用Diskpart创建、扩展或删除磁盘分区

    在Windows Server环境下进行基本的磁盘操作时,管理员可以使用Disk Partition Utility或Diskpart等工具.后者是一个命令行解释器,可作为磁盘管理工具. 管理员可以使 ...

  2. 【VerySky原创】RPR_ABAP_SOURCE_SCAN

    [VerySky原创]RPR_ABAP_SOURCE_SCAN 扫描 ABAP 报表源

  3. Redis+Django(Session,Cookie)的用户系统

    一.Django authentication django authentication提供了一个便利的user api接口,无论在py中 request.user,参见Request and re ...

  4. FoxMail的Bug

    Foxmail 7.2 build6.040,win7中文专业版 下载腾讯的企业邮箱的邮件, 自动配置为imap收邮件 收件箱应该为1740封 邮件 实际foxmail却只收到1500多封 改成pop ...

  5. Linux--Ubuntu12.04安装NDK

    前言 本篇博客将介绍如何在Ubuntu12.04下安装Android NDK,在其他版本的Ubuntu下,方法也类似.由于Android NDK不能单独作为Android应用程序来运行,因此,使用An ...

  6. Scala 深入浅出实战经典 第75讲:模式匹配下的For循环

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

  7. java bean、List、数组、map和Json的相互转化

    工程 json包为  代码 package com.my.json; public class ChildBean { private String childName; private String ...

  8. eclipse 运行报java.lang.OutOfMemoryError: PermGen space解决方法

    一.在window下eclipse里面Server挂的是tomcat6,一开始还是以为,tomcat配置的问题,后面发现,配置了tomcat里面的catalina.bat文件,加入 set JAVA_ ...

  9. 面向.Net程序员的Sql版本管理

    代码版本管理基本上程序员们都知道 TFS GIT SVN等等 但是对于数据库版本管理 java程序员或许会了解一些 但是.Net程序员收获的资料应该不多. 特别是现在云概念使用越来越广的情况下,与应用 ...

  10. [原]quick集成spine动画

    更新说明: 新增了骨骼绑定node用法 参考:http://blog.csdn.net/n5/article/details/21795265 在SkeletonRenderer.h 和cpp里面新加 ...