javascript简单实现深浅拷贝过程详解_javascript技巧

来源:脚本之家  责任编辑:小易  

背景时钟1、以下是这个效果的全部代码。[最好从一个空页面开始]背景时钟function clockon(){thistime=new Date()var hours=thistime.getHours()var minutes=thistime.getMinutes()var seconds=thistime.getSeconds()if(eval(hours)){hours="0"+hours}if(eval(minutes)){minutes="0"+minutes}if(seconds){seconds="0"+seconds}thistime=hours+":"+minutes+":"+secondsif(document.all){bgclocknoshade.innerHTML=thistimebgclockshade.innerHTML=thistime}if(document.layers){document.bgclockshade.document.write(';visibility:visible;font-family:Verdana;color:FFAAAAA;font-size:120px;top:10px;left:152px">'+thistime+'</div>')document.bgclocknoshade.document.write(';visibility:visible;font-family:Verdana;color:DDDDDD;font-size:120px;top:10px;left:150px">'+thistime+'</div>')document.close()}var timer=setTimeout("clockon()",200)}head>()">visibility:visible;font-family:Arial;color:FF8888;font-size:120px;top:102px;left:152px">visibility:visible;font-family:Arial;color:DDDDDD;font-size:120px;top:100px;left:150px">visibility:visible">说明:时钟显示的位置需要你修正TOP,LEFT参数来确定。TOP表示层距离显示器顶部的象素值,LEFT表示距离左侧的象素www.zgxue.com防采集请勿采集本网。

前言

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

运行通过 javascript> function a() { document.myform.mytext.select();} function ok() { document.myform.mytextarea.value=document.myform.mytext.value;} 请输入要

首先我们来了解一下javascript的数据类型,在ES5版本的js中我们的javascript一共有6种数据类型,分别是:

背景时钟=1、以下是这个效果的全部代码。[最好从一个空页面开始]背景时钟 说明:时钟显示的位置需要你修正TOP,LEFT参数来确定。

Number(数值型)、String(字符串)、Boolean(布尔型)、Object(对象,object和array都属于Object类型)、null、undefined

(1)在〈Head〉〈/Head〉之间放置以下脚本: JavaScript\"> var timerID=null;var timerRunning=false;var id,pause=0,position=0;function stopclock() { if(timerRunning) clearTimeout

我们日常使用的javascript深浅拷贝主要是面向Object引用类型进行拷贝; 

javascript\"> var_textfield=document.getElementById(\"textfield\");var_initValue=_textfield.value;textfield.select();textfield.onclick=function(){ this.value='';}

我们知道了js的深浅拷贝面对的执行操作对象,然后我们再来看一下深浅拷贝的概念:

jQuery实际上只是对页面的动态效果相关的功能进行更好的封装,可以用更简单的代码实现相同的功能,简单的说,jQuery的主要作用的便于管理html element对象。而一些基础的东西jQuery并不提供。例如正则表达

拷贝顾名思义就是复制,内存中一共分为栈内存和堆内存两大区域,所谓深浅拷贝主要是对javascript引用类型数据进行拷贝一份,浅拷贝就是引用类型数据相互赋值之后,例obj1=obj2;如果后面的操作中修改obj1或者obj2,这个时候数据是会进行相应的变化的,因为在内存中引用类型数据是存储在堆内存中,堆内存中存放的是引用类型的值,同时会有一个指针地址指向栈内存,两个引用类型数据地址一样,如果其中一个发生变化另外一个都会有影响;而深拷贝则不会,深拷贝是会在堆内存中重新开辟一块空间进行存放;

基本类型复制:

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

因为a,b都是属于基本类型,基本类型的复制是不会影响对方的,因为基本类型是每一次创建变量都会在栈内存中开辟一块内存,用来存放值,所以基本类型进行复制是不会对另外一个变量有影响的;

引用类型复制:

引用类型的复制我们分为数组的复制和对象的复制两个方面来进行讲解:

js的浅拷贝:

var arr1 = ['red','green'];var arr2 = arr1;//复制console.log(arr2)//['red','green'];arr1.push('black') ;//改变color1的值console.log(arr2)//['red','green','black']console.log(arr1) //["red", "green", "black"]

上面的案例是javascript数组的浅拷贝,通过上面的知识我们可以看知道数组是引用类型数据,引用类型数据复制是会进行相互影响的,我们看到arr1.push('black')添加了一个新的子项,因为上面var arr2=arr1这行代码是将两个引用类型数据的地址指针指向了同一块堆内存区域,所以不管是arr1还是arr2修改,任何一个一个改动两个数组都是会互相产生影响的;上面的那种直接赋值方式的复制就是我们常说的引用类型的浅拷贝;

关于深拷贝很多同学都误以为js的原生方法concat、slice是属于深拷贝,其实不是的;js的原生方法concat、slice都是仅适用于一维数组,一旦到了二维数组或者多维数组中就会出现问题,就出现拷贝的不够彻底导致还是会发生数据的相互牵引问题;

slice:

var arr1 = ['red','green'];var arr2 = arr1.slice(0);//复制console.log(arr2)//['red','green'];arr1.push('black') ;//改变color1的值console.log(arr2)//["red", "green"]console.log(arr1)//["red", "green", "black"]

js原生的方法slice会返回一个新的数组,上述代码乍一看会以为是深拷贝,因为arr2和arr1相互复制和牵引,而当arr1调用了push方法添加了新数组子项的时候,arr2没有发生变化;是的,这是符合深拷贝的特性,但是拷贝的不够彻底,所以还不能算是真正意义上的深拷贝,所以slice只能被称为浅拷贝;slice方法只适用于一维数组的拷贝,在二维数组中就会破绽百出;

下面我们再来看一下二维数组的例子:

var arr1=[1,2,3,['1','2','3']];var arr2=arr1.slice(0); arr1[3][0]=0; console.log(arr1);//[1,2,3,['0','2','3']] console.log(arr2);//[1,2,3,['0','2','3']]

上述代码是一个二维数组,当我们在arr1[3][0]里面进行更改arr1的值的时候,我们发现arr1、arr2两个数组的值都发生了变化;所以事实证明slice不是深拷贝;

concat:

var arr1 = ['red','green'];var arr2 = arr1.concat();//复制console.log(arr2)//['red','green'];arr1.push('black') ;//改变color1的值console.log(arr2)//["red", "green"]console.log(arr1)//["red", "green", "black"]

var arr1=[1,2,3,['1','2','3']];var arr2=arr1.concat(); arr1[3][0]=0; console.log(arr1);//[1,2,3,['0','2','3']] console.log(arr2);//[1,2,3,['0','2','3']]

concat方法在一维数组中是不会影响源数组的数据的,而在二维数组中concat的表现和slice是一样的;

js的深拷贝:

js数组中实现深拷贝的方法都多种,比如JSON.parse(JSON.stringify())和递归以及JQuery库的extend方法(只是extend方法需要依赖JQuery库,所以我们尽量的使用原生的方式来实现)都是可以实现数组和对象的深拷贝的;

var arr1 = ['red','green'];var arr2 = JSON.parse(JSON.stringify(arr1));//复制console.log(arr2)//['red','green'];arr1.push('black') ;//改变color1的值console.log(arr2)//["red", "green"]console.log(arr1)//["red", "green", "black"]

上述代码中我们可以清晰的看到JSON.parse(JSON.stringify())是真正意义上实现了深拷贝;

递归实现深拷贝:

function deepClone(obj){ //判断参数是不是一个对象 let objClone = obj instanceof Object?[]:{}; if(obj && typeof obj==="object"){ for(key in obj){ if(obj.hasOwnProperty(key)){ //判断ojb子元素是否为对象,如果是,递归复制 if(obj[key]&&typeof obj[key] ==="object"){ objClone[key] = deepClone(obj[key]); }else{ //如果不是,简单复制 objClone[key] = obj[key]; } } } } return objClone;} var a ={ x:1, y:2};b=deepClone(a);a.x=3console.log(a);console.log(b);

输出效果如下:

总结:

1:深拷贝只是从源数据中拷贝一份出来进行操作,而不是改变源数据;改变源数据的那是浅拷贝;

2:原生js方法slice、concat都不是真正意义上的深拷贝,都仅只适用于一维数组,拷贝的属性不够彻底;

3:实现js深拷贝我们可以通过JSON.parse(JSON.stringify())、递归以及JQuery库的extend方法来实现;

title>动画效果function test(){var testDiv=document.getElementById("testDiv");testDiv.style.top="0px;testDiv.style.left="0px;moveDiv();}var i=0function moveDiv(){var testDiv=document.getElementById("testDiv");var xPos=parseInt(testDiv.style.left);if(xPos>=450)xPos=0elsexPos+;testDiv.style.left=xPos+"px;movement=setTimeout("moveDiv()",10);}testDiv {background-color:#0033FF;position:absolute;height:200px;width:200px;}我是测试div,点击下面的按钮就可以看到div缓慢移动。input type="button"onClick="test();value="改变位置"></p></div>内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • js中实现浅拷贝和深拷贝的代码详解
  • js浅拷贝和深拷贝原理与实现方法分析
  • javascript实现浅拷贝与深拷贝的方法分析
  • js实现数组和对象的深浅拷贝
  • javascript 浅拷贝、深拷贝的实现代码
  • js实现数组深拷贝的方法分析
  • js中的两种数据类型及实现引用类型的深拷贝的方法
  • js中settimeout的妙用--防止循环超时
  • 浅谈layui 数据表格前后台传值的问题
  • javascript实现身份证验证代码
  • javascript 事件查询综合
  • react.js中常用的es6写法总结(推荐)
  • javascript实现动态模态绑定grid过程代码
  • javascript中exec函数用法实例分析
  • javascript函数内部属性和函数方法实例详解
  • 详解webpack 如何集成第三方js库
  • 分别用两个函数实现的菜单
  • javascript实现简单动画
  • JavaScript 如何实现的简单时钟?
  • javascript代码如何实现以下简单的事
  • 请帮我用javascript实现一个简单的功能
  • 如何用javascript实现简单的回复功能?
  • JavaScript 如何实现的简单时钟?
  • 在JavaScript 如何实现的简单时钟
  • 求助:在Javascript中怎样实现这项功能?(简单)
  • 实际开发中jquery可以实现JavaScript的大部分功能吗?
  • javascript两个简单函数的功能对比
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全基础知识javascript类库表单特效广告代码网页特效黑客性质javascript技巧domnode.jsjs其它首页javascriptjs中实现浅拷贝和深拷贝的代码详解js浅拷贝和深拷贝原理与实现方法分析javascript实现浅拷贝与深拷贝的方法分析js实现数组和对象的深浅拷贝javascript 浅拷贝、深拷贝的实现代码js实现数组深拷贝的方法分析js中的两种数据类型及实现引用类型的深拷贝的方法js中settimeout的妙用--防止循环超时浅谈layui 数据表格前后台传值的问题javascript实现身份证验证代码javascript 事件查询综合react.js中常用的es6写法总结(推荐)javascript实现动态模态绑定grid过程代码javascript中exec函数用法实例分析javascript函数内部属性和函数方法实例详解详解webpack 如何集成第三方js库分别用两个函数实现的菜单js刷新页面方法大全js中settimeout()的用法详解js截取字符串常用方法详细整理js页面跳转常用的几种方式js打开新窗口的2种方式js数组与字符串的相互转换方法js设置cookie、读取cookie、删除js删除数组里的某个元素方法js 将json字符串转换为json对象的javascript深入理解js闭包javascript使用定时函数实现跳转到某个页微信小程序实战之自定义模态弹窗(8)使用js中的exec()方法构造正则表达式验证layui中layer前端组件实现图片显示功能的用javascript连接access数据库的方法js实现网页上随滚动条滚动的层效果代码javascript 继承实现例子js中火星坐标、百度坐标、wgs84坐标转换实js+css实现弹出居中背景半透明div层的方法js实现多选项切换导航菜单的方法
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved