JavaScript有五种基本数据类型(Undefined, null, Boolean, String, Number),还有一种复杂的数据类型,就是对象。

Undefined 其实是已声明但没有赋值的变量的输出结果,null其实就是一个不存在的对象的结果

  • 对于简单的数据类型
    它们值在占据了内存中固定大小的空间,并被保存在栈内存中。 当一个变量向另一个变量复制基本类型的值时,会创建这个值的副本,还有就是不能给基本类型的值添加属性。

    1
    2
    3
    4
    var a = 1;
    var b = a;
    a.attr = 'long';
    console.log(a.attr) //undefined

    上边代码中a就是简单数据类型(number),b就是a的副本,它们两者都占有不同位置,但相等的内存空间。

  • 对于复杂的数据类型
    复杂的数据类型即引用类型,它的值是对象,保存在堆内存中,包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针。从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象。

    1
    2
    3
    4
    5
    6
    7
    8
    var obj = {
    name: 'long',
    age: 0
    };
    var obj2 = obj;
    obj2.c = 5;
    console.log(obj); //Oject {name: 'long', age: 0, c: 5}
    console.log(obj2); //Oject {name: 'long', age: 0, c: 5}

我们可以看到obj赋值给obj2后,当我们更改其中一个对象的属性值,两个对象都发生了改变,究其原因是因为obj和obj2这两个变量都指向同一个指针,赋值是复制了指针,所以当我们改变其中一个值,就会影响另一个变量的值。

浅拷贝

其实上边的代码就是浅拷贝,有时候我们只是想备份数组,但是只是简单让它赋给一个变量,改变其中一个,另外一个就紧跟着改变,但很多时候这不是我们想要的。

1
2
3
4
5
6
7
8
var obj = {
name:'wsscat',
age:0
}
var obj2 = obj;
obj2['c'] = 5;
console.log(obj);//Object {name: "wsscat", age: 0, c: 5}
console.log(obj2);////Object {name: "wsscat", age: 0, c: 5}

深拷贝

数组

对于数组我们可以使用slice()和concat()方法来解决上面的问题。

  • slice

    1
    2
    3
    4
    5
    var arr = ['ge', 'yu', 'long'];
    var arrCopy = arr.slice(0);
    arrCopy[0] = 'gai';
    console.log(arr) // ['ge', 'yu', 'long']
    console.log(arrCopy) // ['gai', 'yu', 'long']
  • concat

    1
    2
    3
    4
    var arr = ['ge', 'yu', 'long'];
    var arrCopy = arr.concat();
    arrCopy[0] = 'gai';
    //console跟上边一样

对象

对象我们可以定义一个新的对象并遍历新的属性去实现深拷贝
原始方法:

1
2
3
4
5
6
7
8
9
10
var obj = {
name: 'geyulong',
age: 0
};
var obj2 = new Object();
obj2.name = obj.name;
obj2.age = obj.age;
obj.name = "gaiyulong";
console.log(obj); // Object {name: 'geyulong', age: 0}
console.log(obj2); // Object {name: 'gaiyulong', age: 0}

当然我们是要封装一个方法来实现深拷贝。

1
2
3
4
5
6
7
8
9
10
11
12
var deepCopy = function(source) {
var result = {};
for(var key in source) {
if(typeof source[key] === 'object') {
result[key] = deepCopy(source[key])
} else {
result[key] = source[key]
}
}
return result;
}
var obj2 = deepCopy(obj);

ShareComments

JavaScript 深浅拷贝的更多相关文章

  1. JavaScript深浅拷贝区别

    分享一篇自己关注的微信订阅号(前端大全)文章:JavaScript浅拷贝与深拷贝 作者:浪里行舟 https://github.com/ljianshu/Blog/issues/5 这里很详细的讲解了 ...

  2. JavaScript深浅拷贝

    深浅拷贝 基本类型和引用类型 ECMAScript 中的变量类型分为两类: 基本类型:undefined,null,布尔值(Boolean),字符串(String),数值(Number) 引用类型: ...

  3. 谈谈JavaScript深浅拷贝

    浅拷贝 function shallowCopy(source){ var newObj = {}; for(var attr in source){ newObj[attr] = source[at ...

  4. javascript简单实现深浅拷贝

    深浅拷贝知识在我们的日常开发中还算是用的比较多,但是之前的状态一直都是只曾听闻,未曾使用(其实用了只是自己没有意识到),所以今天来跟大家聊一聊js的深浅拷贝: 首先我们来了解一下javascript的 ...

  5. JavaScript数据存储和深浅拷贝实际运用

    JavaScript分两种数据类型.1.简单数据类型有:number, string, boolean, undefined和null当声明一个简单数据类型的变量时,在内存中会把数据存在栈里.2.复杂 ...

  6. JavaScript中的事件委托机制跟深浅拷贝

    今天聊下JavaScript中的事件委托跟深浅拷贝 事件委托 首先呢,介绍一下事件绑定 //方法一:通过onclick <button onclick="clickEvent()&qu ...

  7. javascript实现深浅拷贝

    深浅拷贝通常是对于引用数据类型进行的(数据类型为:对象(Object).数组(Array).函数(Function)) 浅拷贝: let obj = {id: 1, name: 2}; let new ...

  8. Javascript 中的深浅拷贝

    工作中经常会遇到需要复制 JS 数据的时候,遇到 bug 时实在令人头疼:面试中也经常会被问到如何实现一个数据的深浅拷贝,但是你对其中的原理清晰吗?一起来看一下吧! 为什么会有深浅拷贝 想要更加透彻的 ...

  9. JavaScript中的深浅拷贝

    深浅拷贝 在JS中,数据类型分为两类: ​ 简单数据类型:Number.Boolean.String.undefined ​ 引用数据类型:Array.Object.Function 简单数据类型通常 ...

随机推荐

  1. 《C程序设计语言》读书笔记----习题1-21

    题目就不写了,大概意思就是:尽量用制表符'\t'替换掉字符串中的空格. 同学们需要注意的是,打印一个制表符'\t',其所占长度不是固定的. 这里要理解“制表符”和“制表符终止位”.“制表符”的作用是使 ...

  2. MySQL导入sql脚本中文乱码设置和常用命令

    1. use database_name; 2. set names utf8; (或其他需要的编码) 3. source example.sql (sql文件存放路径) Mysql安装目录数据库目录 ...

  3. abs函数

    absolute 绝对值函数 abs函数是一个取绝对值函数,你得确保ABS()括号里的表达式所计算出的结果是数字,String是字符串的意思,你括号你的数据肯定是字符串了,如果A.B两变量你是这样定义 ...

  4. Chapter5 – 碰撞检测

    主人公能够放子弹了,虽然子弹看起来很美,但是怎么样来打到妖怪? 在这一章我们介绍一下最简单的碰撞检测方法去实现它. 首先第一个,我们有必要保存每个妖怪和子弹的指针,来够追踪他们的位置. 在这个游戏中我 ...

  5. OI队内测试——石门一

    T1: 题目大意: 给你一个立方体,每个面上有些数字,给你一个数字K,你可以玩K轮游戏, 每轮你会将每个面上的数均分为4份,分给相邻的面,求K轮游戏后,上面的数字是 依次给你前.后.上.下.左.右的起 ...

  6. 安卓 webview背景色的设置

    第一步:webview的xml属性设置:android:layerType = "software"(关闭webview硬件加速,颜色设置才可以起效果) 第二步:webview所在 ...

  7. LVS 负载均衡解决方案 (windows IIS)

    LVS 负载均衡解决方案 因为我们的产品运行的主流平台是WINDOWS+IIS+SQLSERVER(2000以上版本),而LVS+KEEPALIVED是LINUX下的四层负载均衡软件.其有如下特点: ...

  8. redis3 list类型

    list类型及操作list是一个链表结构,主要功能是push,pop.获取一个范围的所有值等,操作中key理解为链表的名字.redis的list类型其实就是一个每个子元素都是string类型的双向链表 ...

  9. SecureCRT 使用

    1. 连接linux 服务器 http://www.cnblogs.com/SimonGao/p/4959274.html

  10. swift 协议传值的实现

    首先呢说下结构 一个ViewController 一个ModelViewController 在ModelViewController中定义了一个协议 这个逻辑 从第一个界面进入第二个界面  从第二个 ...