从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 类似于拷贝指针和 值? ...占坑先.
随机推荐
- .NET CORE 中使用AutoMapper进行对象映射
简介 AutoMapper uses a fluent configuration API to define an object-object mapping strategy. AutoMappe ...
- Vue Mixin 与微信小程序 Mixins 应用
什么是Mixin(混入) Mixin是一种思想,用来实现代码高度可复用性,可以针对属性复制实现代码复用的想法进行一个扩展,就是混入(mixin).混入并不是复制一个完整的对象,而是从多个对象中复制出任 ...
- 时序数据库连载系列:指标届的独角兽Prometheus
简介 Prometheus是SoundCloud公司开发的一站式监控告警平台,依赖少,功能齐全.于2016年加入CNCF,广泛用于 Kubernetes集群的监控系统中,2018.8月成为继K8S之后 ...
- .NET CAD二次开发学习 直线画矩形并转换成组
主要代码: using System;using System.Collections.Generic;using System.Linq;using System.Text;using System ...
- K2制作流程
K2流程制作注意事项 1:分析需求 2:实施 步骤1:绘制流程图 步骤2:添加datafield[必备:ActJumped IsPass] 步骤3:添加线规则(如下图所示,在添加完毕规则之后,再给同 ...
- Spring MVC深入学习
一.MVC思想 MVC思想简介: MVC并不是java所特有的设计思想,也不是Web应用所特有的思想,它是所有面向对象程序设计语言都应该遵守的规范:MVC思想将一个应用部分分成三个基本部 ...
- javascript函数调用中的方法调用模式
最近想起来之前看过的一种js语法,感觉很实用,但是又想不起来具体的写法.然后在网上浏览了一段时间,终于成功的再现了记忆中的那种语法,嗯~,还是那个熟悉的味道! 代码如下: <script> ...
- js 控制随机数生成概率
基本思路:把Math.random()生成的数看着百分比,然后定义每个整数值取值范围. 'use strict'; export default class GL { /** * 构造函数 * @pa ...
- Android 简单统计文本文件字符数、单词数、行数Demo
做的demo是统计文本文件的字符数.单词数.行数的,首先呢,我们必须要有一个文本文件.所以我们要么创建一个文本文件,并保存,然后再解析:要么就提前把文本文件先放到模拟器上,然后检索到文本名再进行解析. ...
- 通过 Sqoop1.4.7 将 Mysql5.7、Hive2.3.4、Hbase1.4.9 之间的数据导入导出
目录 目录 1.什么是 Sqoop? 2.下载应用程序及配置环境变量 2.1.下载 Sqoop 1.4.7 2.2.设置环境变量 2.3.设置安装所需环境 3.安装 Sqoop 1.4.7 3.1.修 ...