一、js 数据类型

javaScritp的数据类型有:数值类型、字符串类型、布尔类型、null、undefined、对象(数组、正则表达式、日期、函数),大致分成两种:基本数据类型和引用数据类型

其中:

    (1)基本数据类型:数值、字符串、布尔、null、undefined (值类型)
  (2)复杂(复合)数据类型:对象 (引用类型)

  基本数据类型保存在栈内存,引用类型保存在堆内存中。根本原因在于保存在栈内存的必须是大小固定的数据,引用类型的大小不固定,只能保存在堆内存中,但是可以把它的地址写在栈内存中以供我们访问

  如果是基本数据类型,则按值访问,操作的就是变量保存的值;如果是引用类型的值,我们只是通过保存在变量中的引用类型的地址来操作实际对象

举例:

var a = 1;//定义了一个number类型
var obj1 = {//定义了一个object类型
name:'obj'
};

1、基本类型的复制

var a = 1;
var b = a;//复制
console.log(b)//
a = 2;//改变a的值
console.log(b)//

赋值的时候,在栈内存中重新开辟内存,存放变量b,所以在栈内存中分别存放着变量a、b各自的值,修改时互不影响

2、引用类型的复制

var color1 = ['red','green'];
var color2 = color1;//复制
console.log(color2)//['red','green'];
color1.push('black') ;//改变color1的值
console.log(color2)//['red','green','black']
color1与color2指向堆内存中同一地址的同一对象,复制的只是引用地址

因此,对于引用类型的复制,简单赋值无用,需要拷贝。拷贝存在两种类型:深拷贝与浅拷贝

二、深浅拷贝

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象
1、浅拷贝
    浅拷贝只是拷贝基本类型的数据,如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,因此存在父对象被篡改的可能,浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存

        var Nation = {  
nation: '中国'
};function extendCopy(p) {  
var c = {};  
for (var i in p) {    
c[i] = p[i];  
}  
return c;
}
var Doctor = extendCopy(Nation);
Doctor.career = '医生';
Doctor.nation = '美国';
console.log(Doctor.nation); // 美国
console.log(Nation.nation); // 中国
console.log(Doctor.career); // 医生
console.log(Doctor.__proto_ === Nation.__proto_) // true
     // 这里涉及到使用拷贝父对象的属性实现继承
        var obj = {
a: "hello",
b:{
a: "world",
b: 21
},
c:["Bob", "Tom", "Jenny"],
d:function() {
alert("hello world");
}
} var obj1 = simpleClone(obj);
console.log('obj1=>>>',obj1);
// 1、
obj1.c = ['mm', "Tom", "Jenny"]; // 一层,作为整体,重写,全改变;改变属性值,不改变原对象
console.log('obj=>>>',obj); //obj.c => ["Bob", "Tom", "Jenny"]
     // 2、
   obj1.c[0] = 'mm'; // 浅拷贝时,改变属性的属性值,改变原对象
console.log('obj=>>>',obj); //obj.c => ["mm", "Tom", "Jenny"]

浅拷贝函数:

       function simpleClone(initalObj) {
var obj = {};
for ( var i in initalObj) {
obj[i] = initalObj[i];
}
return obj;
}

2、深拷贝

深拷贝就是能够实现真正意义上的数组和对象的拷贝。递归调用"浅拷贝"。(深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象)

深拷贝函数:

写法一:
function deepClone(initalObj, finalObj) {
var obj = finalObj || {};
for (var i in initalObj) {
var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
if(prop === obj) {
continue;
} if (typeof prop === 'object') {
obj[i] = (prop.constructor === Array) ? [] : {};
arguments.callee(prop, obj[i]);
} else {
obj[i] = prop;
}
}
return obj;
} 写法二:
function deepClone(initalObj, finalObj) {
var obj = finalObj || {};
for (var i in initalObj) {
var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
if(prop === obj) {
continue;
} if (typeof prop === 'object') {
obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
} else {
obj[i] = prop;
}
}
return obj;
}

三、深拷贝的应用实例

        // jquery 有提供一个$.extend可以用来做 Deep Copy。
var $ = require('jquery');
var obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
var obj2 = $.extend(true, {}, obj1);
console.log(obj1.b.f === obj2.b.f);
// false // 函数库lodash,有提供_.cloneDeep用来做 Deep Copy。
var _ = require('lodash');
var obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);
// false

js 深浅拷贝 笔记总结的更多相关文章

  1. JS深浅拷贝及其实现

    基本数据类型和引用数据类型 JS数据分为基本数据类型和引用数据类型.基本数据类型的变量存储在栈中,引用数据类型则存储在堆中,引用数据类型的存储地址则保存在栈中. 下面来看一个小例子 // 基本数据类型 ...

  2. jQuery开发插件的两个方法 js 深浅拷贝

    1.jQuery.extend(object);为扩展jQuery类本身.为类添加新的方法.由全局函数来调用, 主要是用来拓展个全局函数 2.jQuery.fn.extend(object);为jQu ...

  3. js深浅拷贝

    作为一枚前段,我们知道对象类型在赋值的过程中其实是复制了地址,从而会导致改变了一方其他也都被改变的情况.通常在开发中我们不希望出现这样的问题,我们可以使用浅拷贝来解决这个情况. 浅拷贝 首先可以通过O ...

  4. 最简js深浅拷贝说明

    1.浅拷贝 浅拷贝是拷贝引用,拷贝后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响.  浅拷贝分两种情况: 1.直接拷贝源对象的引用 2. 源对象拷贝实例,但其属性对象(类型为Object, ...

  5. JS 深浅拷贝

    首先理解概念 浅拷贝: 只复制对象的基本类型, 对象类型, 仍属于原来的引用. 深拷贝: 不紧复制对象的基本类, 同时也复制原对象中的对象.就是说完全是新对象产生的. 首先看浅拷贝 //浅拷贝 var ...

  6. JS中深浅拷贝 函数封装代码

    一.了解 基本数据类型保存在栈内存中,按值访问,引用数据类型保存在堆内存中,按址访问. 二.浅拷贝 浅拷贝只是复制了指向某个对象的指针,而不是复制对象本身,新旧对象其实是同一内存地址的数据,修改其中一 ...

  7. js 基础数据类型和引用类型 ,深浅拷贝问题,以及内存分配问题

    js 深浅拷贝问题 浅拷贝一般指的是基本类型的复制 深拷贝一般指引用类型的拷贝,把引用类型的值也拷贝出来 举例 h5的sessionStorage只能存放字符串,所以要存储json时就要把json使用 ...

  8. JS--变量及深浅拷贝

    JS变量分为基本类型和引用类型 基本类型数据包括Number, String, Boolean, Null, Undefined五种类型: 引用数据类型包括Array, Date, RegExp, F ...

  9. 【 js 基础 】 深浅拷贝

    underscore的源码中,有很多地方用到了 Array.prototype.slice() 方法,但是并没有传参,实际上只是为了返回数组的副本,例如 underscore 中 clone 的方法: ...

随机推荐

  1. 【VS开发】【DSP开发】WinDriver简介(或介绍)

    WinDriver for Windows简化并自动化了用户模式Windows设备驱动程序的开发,支持设备包括PCI / CardBus / ISA/ PCI-104 / PCMCIA * / PMC ...

  2. 【VS开发】关于在CFormView中实现CListCtrl控件的注意事项

    [VS开发]关于在CFormView中实现CListCtrl控件的注意事项 标签(空格分隔): [VS开发] 今天调试中发现了一项非常令人恼怒的事情,本来早都知道在CFormView中没有了像在对话框 ...

  3. XML中不能识别&符号, 需要转义吗?

    “&”在XML中是具有特殊含义的,是转义字符的前缀,如果要想用这个字符就需要转义.遇到“&”就替换成“&amp”就好了; xml所有转义符   和 & & 大于 ...

  4. 2019牛客暑期多校训练营(第九场)-D Knapsack Cryptosystem (折半搜索)

    题目链接:https://ac.nowcoder.com/acm/contest/889/D 题意:题意简单,从大小为36的集合中选若干元素使得他们的和为sum. 思路:第一感觉用搜索,复杂度为2^3 ...

  5. 线性基求交(2019牛客国庆集训派对day4)

    题意:https://ac.nowcoder.com/acm/contest/1109/C 问你有几个x满足A,B集合都能XOR出x. 思路: 就是线性基求交后,有几个基就是2^几次方. #defin ...

  6. # G++出现cannot open output file … : Permission denied问题

    G++出现cannot open output file - : Permission denied问题 这是因为之前的编译运行程序没有退出,导致下一次编译运行无法进行,这应该是命令行下运行才可能出现 ...

  7. php面试相关整理

    1.HTTP Keep-Alive的作用 作用:Keep-Alive:使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接.Web服务器,基 ...

  8. python *****【异常处理】*****

    try: val = input('请输入数字:') num = int(val) except Exception as e: print('操作异常') # import requests # # ...

  9. DRF cbv源码分析 restful规范10条 drf:APIView的源码 Request的源码 postman的安装和使用

    CBV 执行流程 路由配置:url(r'^test/',views.Test.as_view()),  --> 根据路由匹配,一旦成功,会执行后面函数(request) --> 本质就是执 ...

  10. Python链表操作(实现)

    Python链表操作 在Python开发的面试中,我们经常会遇到关于链表操作的问题.链表作为一个非常经典的无序列表结构,也是一个开发工程师必须掌握的数据结构之一.在本文中,我将针对链表本身的数据结构特 ...