从JS的深拷贝与浅拷贝到jq的$.extend()方法
一、堆内存与栈内存
堆和栈都是内存中划分出来的用来存储的区域,栈为自动分配的内存空间,它由系统自动释放,堆为动态分配的内存,大小不定也不会自动释放。
二、js基本数据类型与引用类型的不同
基本数据类型(boolean,undefined,null,string,number)
1.基本数据类型存放在栈内存中
是存放在栈中的简单数据段,数据大小确定,内存空间大小可以分配,是直接按值存放的,所以可以直接访问。
2、基本数据类型值不可变
js中给基本类型赋值或操作基本类型数据时,并没有改变基本类型的原始值,数字和布尔类型的值显然是不可变的,字符串虽然有很多方法去操作,但都是在创造一个新的字符串,它的原始值并没有改变。
3、基本数据类型的比较是值的比较
只要他们的值是相等的就认为他们是相等的。
var a = 1;
var b = 1;
console.log(a == b);//true
这里最好用严格等,否则会进行类型转换;
var a = 0;
var b = '0';
console.log(a == b);//true
console.log(a === b); //false
引用类型(数组】、对象、函数)
1、引用类型存放在堆内存
2、引用类型值可变
3、引用类型的比较是引用的比较
var a = [1,2,3];
var b = [1,2,3];
console.log(a === b);//false
比较两个对象的引用,是看两个引用是否指向同一个对象
基本数据类型与引用类型赋值比较
基本数据类型赋值是值的传递,先在栈内存中开辟一段内存,再把值赋值到新的栈中
var a = 10;
var b = a; a ++ ;
console.log(a); //
console.log(b); //
引用类型的赋值是传址,就是说赋值时是保存在栈中的变量的地址的赋值,这样两个变量指向同一个对象,所以两个变量之间会相互影响;
var a = {};
var b = a;
a.name = "qy";
console.log(a.name);//qy
console.log(b.name);//qy
b.age = 22;
console.log(a.age);//
console.log(b.age);//22
console.log(a === b);//true
赋值并不是浅拷贝,赋值和浅拷贝之间的区别
var obj1 = { //原始数据
"name" : "zhangsan",
"age" : "22",
"language" : [1, [2, 3], [4, 5]]
}
var obj2 = obj1;//赋值得到
var obj3 = shallowCopy(obj1);//浅拷贝得到
function shallowCopy(src) {
var dst = {};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
dst[prop] = src[prop];
}
}
return dst;
}
obj2.name = "lisi";//改变赋值得到的obj2的基本类型属性name,最后结果为原始数据里的属性也随之改变
obj3.age = "11";//改变浅拷贝得到的obj3的基本类型属性age,结果为原始数据的age属性并没有改变
obj2.language[1] = ['a', 'b'];//改变赋值得到的obj2的引用类型属性,结果为原始数据及由原始数据浅拷贝得到的obj3的language属性均被改变
obj3.language[2] = ['c', 'd'];//改变浅拷贝得到的obj3的引用类型属性,结果为原始数据及有原始数据赋值得到的obj2的language属性均被改变
console.log(obj1);//name:lisi,age:22,language:[1,[a,b],[c,d]]
console.log(obj2);//name:lisi,age:22,language:[1,[a,b],[c,d]]
console.log(obj3);//name:zhangsan,age:11,language:[1,[a,b],[c,d]]
结论:(首先需要明确深拷贝与浅拷贝都是针对引用类型而言的,基本数据类型不涉及到深拷贝与浅拷贝)
@1 引用类型的赋值是地址的传递,即赋值得到的新数据与原数据指向堆内存中的同一个对象,两者之间仍会互相影响;
@2 浅拷贝是通过创建一个新的对象(数组,对象),依次去拷贝对象的每一个属性,此时如果对象的属性为一个引用类型,那么拷贝过来的引用类型属性依然是指向与原数据的引用类型属性地址相同的一个对象,因此通过浅拷贝得到的新数据,与原数据的引用类型属性会相互影响;
@3 那么深拷贝是怎样的呢,深拷贝就是要做到新数据与原数据完全的互不影响(无论是基本类型还是引用类型);
三、如何进行深拷贝?
思路:递归调用浅拷贝方法,拷贝每一层次的对象属性;以下为zepto的extend方法
$.extend = function(target) {
var deep,
args = slice.call(arguments, 1);
if (typeof target == 'boolean') {
deep = target;
//target取第二个参数
target = args.shift();
}
//遍历后面的参数,都合并到target上面
args.forEach(function(arg){
extend(target, arg, deep)
})
return target;
}
function extend(target, source, deep) {
for (key in source) {
//是深拷贝且为数组或者对象时
if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
//source[key]是对象,而target[key]不是对象,则target[key]初始化一下,否则递归出错
if (isPlainObject(source[key]) && isPlainObject(target[key])) {
target[key] = {};
}
//source[key]是数组,而target[key]不是数组也要初始化一下
if (isArray(source[key]) && !isArray(target[key])) {
target[key] = [];
}
//执行递归
extend(target[key], source[key], deep);
} else if (target[key] !== undefined) {
target[key] = source[key];
}
}
}
四、$.extend()方法(jquery的extend扩展方法)
1、原型:extend(dest,src1,src2,src3...);
含义:将src1,src2,src3...合并到dest中,返回值为合并后的dest
2、dest可为{}
var newSrc=$.extend({},src1,src2,src3...)//也就是将"{}"作为dest参数。
含义: 这样就可以将src1,src2,src3...进行合并,然后将合并结果返回给newSrc了;
例:
var result=$.extend({},{name:"Tom",age:21},{name:"Jerry",sex:"Boy"})
//结果为:
result={name:"Jerry",age:21,sex:"Boy"}
可见此方法中后面的参数如果和前面的参数存在相同的名称,那么后面的会覆盖前面的参数值。
3.重载原型1:省略dest参数,则该方法就只能有一个src参数,而且是将该src合并到调用extend方法的对象中去
例:
$.extend({
hello:function(){alert('hello');}
});
//将hello方法合并到jquery的全局对象中去
4、重载原型2extend(boolean,dest,src1,src2,src3...)
含义:第一个参数boolean代表是否进行深度拷贝,其他参数同上;
var result = $.extend(false, {}, {name: "a", location:{city: "beijing", pos: 1000}}, {age: 12, location:{city: "hanguo", age: 20}});
result= {name: "a", age: 12, location: {city: "hanguo", age: 20}}}
从JS的深拷贝与浅拷贝到jq的$.extend()方法的更多相关文章
- 【js】深拷贝和浅拷贝区别,以及实现深拷贝的方式
一.区别:简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,如果B没变,那就是深拷贝. 此篇文章中也会简单阐述到栈堆,基本数据类型与引用数据类型,因为这 ...
- JS实现深拷贝,浅拷贝的方法
在 JS 中,函数和对象都是浅拷贝(地址引用):其他的,例如布尔值.数字等基础数据类型都是深拷贝(值引用). 深拷贝 JSON.parse(JSON.stringify(src)):这种方法有局限性, ...
- js引用类型深拷贝、浅拷贝方法封装
引用类型的深拷贝.浅拷贝在前端领域一直是个很重要的知识点,不仅在业务中频繁使用,也是面试官们喜欢考的的知识点之一.本篇将封装引用类型的深拷贝.浅拷贝方法,并解决在封装过程中出现的问题. 一.浅拷贝 浅 ...
- JS JavaScript深拷贝、浅拷贝
浅拷贝:浅拷贝只是复制了内存地址,如果原地址中的对象改变了,浅拷贝出来的对象也会相应改变. 深拷贝:开辟了一块新的内存存放地址和地址指向的对象,原地址的任何对象改变了,深拷贝出来的对象不变. 浅拷贝数 ...
- js的深拷贝和浅拷贝
一.数组的深浅拷贝 在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致 ...
- js实现深拷贝和浅拷贝
浅拷贝: 思路----------把父对象的属性,全部拷贝给子对象,实现继承. 问题---------如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,不会开辟新栈,不是 ...
- js对象深拷贝与浅拷贝
浅拷贝 把a赋值给b,a与b指向相同的内存,修改b值,a也会跟着改变. var a = "aa"; var b = a; b = "bb"; 这个时候a也变成了 ...
- js对象深拷贝、浅拷贝
浅拷贝1 //浅拷贝1 let obj01 = { name: 'Lily', age: '20', time: ['13', '15'], person: { name: 'Henry', age: ...
- js 的 深拷贝 和 浅拷贝
http://www.cnblogs.com/yichengbo/archive/2014/07/10/3835882.html 类似于拷贝指针和 值? ...占坑先.
随机推荐
- Chapter 5 Blood Type——32
"Where are you all going, exactly?" He was still looking ahead, expressionless. “真的,你要去哪里? ...
- 痞子衡嵌入式:开启NXP-MCUBootUtility工具的HAB签名功能 - CST(中英双语)
1 Reason for enabling HAB signature function 为什么要开启HAB签名功能 NXP-MCUBootUtility is a tool designed for ...
- IntelliJ IDEA如何激活?
本文使用的IDEA的版本是:14.0.3 下载IDEA授权服务器(下载地址见最后),并解压,打开解压后的IntelliJIDEALicenseServer目录,可以看到如下的两个文件: Intelli ...
- js实现复制文本内容到剪切板
function copyUrl() { var Url2=document.getElementById("url").innerText; var oInput = docum ...
- 原生 table css实现操作按钮固定右侧及底部滚动 IE不会卡死
需求的表格比较复杂(各种合并新增删除),elementUi的table组件无法满足需求,故而写了原生table,且与其他用了table组件的表格保持一致. 贴一下简单的代码,只实现操作按钮固定右侧以及 ...
- 使用GDB调试Android Native 层代码
--------------步骤:0. adb root0. adb shell0. ps | grep browser1. gdbserver :5039 --attach pid2. adb fo ...
- Java:配置环境(Mac)——MySQL
1.官网下载 2.双击开始安装,一直下一步 用旧版的密码加密 自己写个密码,最少8位 3.测试 打开系统偏好设置 4.mysql需要在系统环境变量里 1)在终端输入mysql,没有指令说明.此时就还不 ...
- selenium-测试框架搭建(十三)
思路 分离业务代码和测试数据,提高代码可维护性,实现自动化,减少重复劳动. 一个测试框架大概由配置文件,测试数据,测试用例,相关文件(发送邮件等),测试日志,断言和测试报告等模块组成. 结构 以页面为 ...
- 【Spring Cloud笔记】 断路器-hystrix
在微服务架构中,一个微服务的超时失败可能导致瀑布式连锁反映,Spring Cloud Netflix 的断路器Hystrix通过自主反馈,防止了这种情况发生.下面介绍简单的断路器使用方法. [step ...
- 【Spring Cloud笔记】Eureka注册中心增加权限认证
在Spring Cloud通过Eureka实现服务注册与发现时,默认提供web管理界面,但是如果在生产环境暴露出来,会存在安全问题.为了解决这个问题,我们可以通过添加权限认证进行控制,具体步骤如下: ...