JavaScript 深浅拷贝
来源:互联网 发布:淘宝diy电脑哪家好 编辑:程序博客网 时间:2024/05/20 00:38
深浅拷贝(deep copy, shallow copy)
深浅拷贝的基础知识是关于值类型和引用类型的区分,可参考《JavaScript 数据类型(值类型/引用类型)》一文
(1)什么是拷贝?
注意:一定在内存中有两个数据副本才是拷贝
问题:
var num1 = 123;var num2 = num1; // 这里内存中数据123有两个副本,因此是拷贝
var obj1 = { name: 'jim' };var obj2 = obj1; //这里内存中数据只有一个,没有拷贝,因此这不是拷贝
(2)深拷贝
拷贝对象的所有数据,两个数据副本在内存中完全独立,就是深拷贝
(3)浅拷贝(相对复杂些)
拷贝的对象不完全,数据副本在内存中还有关联,就是浅拷贝
(4)理解深浅拷贝
深浅拷贝只有在对象含有引用类型的成员时才考虑。
function Person( name ) { this.name = name; this.copy = function () { var tmp = new Person( this.name ); return tmp; }}var p1 = new Person( '张三' );var p2 = p1.copy();// 这里没有深浅拷贝之分
浅拷贝:
// 浅拷贝function Person( name ) { this.name = name; this.car = null; this.shallowCopy = function () { var tmp = new Person(); //拷贝出来的副本 for( var k in this ) { tmp[ k ] = this[ k ]; // 如果是值类型, 就直接拷贝了, 如果是引用类型, 就没有拷贝 } return tmp; };}function Car ( name ) { this.name = name;} var p1 = new Person( '李四' );p1.car = new Car( '劳斯莱斯' );var p2 = p1.shallowCopy();
深拷贝:
// 深拷贝// 1> 首先有一个函数, 该函数的特点是 深拷贝一个对象, 并将对象的拷贝结果返回// 2> 在函数内部实现算法, 首先准备一个对象// 3> 遍历目标对象中的所有属性// 4> 判断属性是否为值类型, 如果是值类型直接赋值// 5> 如果是引用类型:// -> 再准备一个对象// -> 再遍历这个属性// -> ...// => 如果是引用类型的对象, 就调用一次自己这个方法function deepCopyHandler( obj ) { // 深拷贝 obj 返回新对象 var tmp = {}; for ( var k in obj ) { if ( typeof obj[ k ] == 'object' ) { // 深拷贝 obj[ k ],递归 tmp[ k ] = deepCopyHandler( obj[ k ] ); } else { tmp[ k ] = obj[ k ]; } } return tmp;}function Person( name ) { this.name = name; this.car = null; this.deepCopy = function () { return deepCopyHandler( this ); }; }function Car ( name ) { this.name = name;} var p1 = new Person( '李四' );p1.car = new Car( '劳斯莱斯' );var p2 = p1.deepCopy();
(5)例:为了兼容ie8,使用递归的方法实现 getElementsByClassName方法
/** * 递归查找有指定类名的元素(进阶方法) * * 可以不新建空数组,也不返回,而将空数组作为参数传入函数 * 且在一开始就限定必须传数组,否则就抛出异常 * 这样的好处是,省去了拼接数组的过程,因为传入的一直是同一个数组 * * @param className 指定类名 * @param tag 总元素 * @returns {Array} */function getByClass(className,arr,tag){ if(typeof arr == 'undefined' || typeof arr.push != 'function'){ throw new Error('传入参数不正确!'); } tag = tag || document;//没传tag就用document元素 var nodes = tag.childNodes;//总元素下的所有子节点 /*遍历*/ for(var i=0; i<nodes.length; i++){ //找到元素节点 if(nodes[i].nodeType == 1){ //找到有类名且包含指定类名的元素 if(nodes[i].className && (' '+nodes[i].className+' ').indexOf(' '+className+' ') > -1){ arr.push(nodes[i]);//推进数组里 } //递归,接着查下一层子元素,找到就推进数组中 getByClass(className,arr,nodes[i]); } }}//使用该方法var divs = [];getByClass('c',divs);//该函数没有返回值,只能执行后从参数中得到结果alert(divs.length);for(var i=0; i<divs.length; i++){ divs[i].style.borderColor = 'green';}
(6)扩展:
深度拷贝对象时,类型不重要,方法是重要的
函数,就是应该共享
遍历的时候应该只考虑当前对象的成员,不考虑原型中的成员(用object.prototype中提供的hasOwnProperty来判断)
如果是数组或伪数组,最好不要一开始就创建{},而是创建[]较好
0 0
- Javascript深浅拷贝
- javascript深浅拷贝
- JavaScript 深浅拷贝
- Javascript深浅拷贝的原理
- javascript 数组的深浅拷贝
- javascript 对象的深浅拷贝
- javascript中对象的深浅拷贝
- Javascript中数据类型&深浅拷贝二
- JavaScript小知识点(一):深浅拷贝
- 深浅拷贝
- 深浅拷贝
- 深浅拷贝
- 深浅拷贝
- 深浅拷贝
- 深浅拷贝
- 深浅拷贝
- 深浅拷贝
- 深浅拷贝
- 适合企业站的织梦常用标签大全
- StringUtils工具类的常用方法
- python小实例--定期检查源目录与备份目录的差异进行备份
- MySQL宽字节注入漏洞分析
- 锚点设置距离顶部高度的方法
- JavaScript 深浅拷贝
- as svn更新不了代码,并且svn checkout时报错Unable to connect to a repository at URL
- myeclipse当中,如何导入或者导出项目
- 使用单例读取配置文件
- HTTP Live Streaming直播(iOS直播)技术分析与实现
- jquery学习笔记二(应用方法)
- Git大文件存储 git-lfs
- thinkphp 3.1模板中的xss漏洞修复
- sqlyog导出excel乱码问题解决方法