-
Notifications
You must be signed in to change notification settings - Fork 735
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Javascript深浅拷贝 #57
Comments
Javascript数组存放函数在javascript中函数也是一种数据,能够像操作一个对象对它进行操作。并且javascript不进行数据类型检查,数组可以存放任何东西,在下面代码中我们不但在数组中存放了函数,并且也可以在存放一个执行函数的返回值,所以数组前两个数据存放都是函数执行返回值 var funcA = function() {
console.log("funcA");
return "hello funA";
}
var funcB = function() {
console.log("funcB");
return "hello funB";
}
var funcC = function() {
console.log("funcC");
return "hello funC";
}
var arr = [funcA(), funcB(), funcC];
console.log(arr);
arr[2](); |
对象中不含有函数的话。JSON解析反解析就行了 |
应该是手滑了吧, |
谢谢,已更正~ |
ES6中有 Object.assign() 方法,应该也可以解决你对于深克隆的需求吧? |
@GreenMelon Object.assign()方法不适于深拷贝,MDN上有说明 |
@yeyuqiudeng concat和slice主要是针对基本数据类型数组的深拷贝,牵涉到多层复杂数据类型即对象的就要再对 |
@flynntsc 嗯嗯,谢谢 |
我这里实现了对象包括数组的深拷贝: Object.prototype.deepCopy=function(){
var obj=null;//用于最后返回一个对象,这个对象是深复制的结果
for(var attr in this){//遍历这个对象的每一个属性
if(this.hasOwnProperty(attr)){//主要是递归自有属性
if(typeof (this[attr]==='object')){//如果对象的属性是一个对象,就递归复制它的每一个属性
if(this[attr]===null){//如果对象为null
obj[attr]=null;
}else if(Object.prototype.toString(this[attr])==='[object Array]'){//如果是个数组
obj[attr]=[];
for(var i=0;i<this[attr].length;i++){
obj[attr].push(this[attr][i].deepCopy());
}
}else{//object
obj[attr]=this[attr].deepCopy();
}
}else{
obj[attr]=this[attr];
}
}
}
return obj;
} |
test.html:12 Uncaught RangeError: Maximum call stack size exceeded |
基本类型在 嗯嗯 by @Wscats |
不错不错👍🏻 |
写得挺好的 |
涨知识啦 |
没看到对循环引用的处理啊 |
function deepCopy(jsonData){ |
@plane-hjh 这样有其他问题 具体可以看我 这篇文章 |
slice、concat、assign都是浅拷贝,如果数据中没有函数,可以直接用JSON来实现拷贝,如果有函数,就得用递归来实现深拷贝,递归实现时,函数依然是公用的; |
typeof 对array和object都返回object,所以没有必要加一层array的判断吧? |
|
js中函数也是一种引用类型数据,a,b指向两个不同的函数,执行的结果也是有区别的发自我的华为手机-------- 原始邮件 --------主题:Re: [Wscats/Good-Text-Share] Javascript深浅拷贝 (#57)发件人:燕睿涛 收件人:Wscats/Good-Text-Share 抄送:陈虎 ,Comment function() {}也算基本数据类型吗
let a = function() {console.log(123);}
let b = a
b = function() {console.log(456);}
执行上面只有,a、b是不同的两个函数,按理说,函数应该存储的也是,求解
—You are receiving this because you commented.Reply to this email directly, view it on GitHub, or mute the thread.
|
let deep_copy = function f(obj) {
let new_value;
if(typeof obj === 'object' && obj != null){
if(obj instanceof Array){
new_value = [];
for(let i=0;i<obj.length;i++){
if(typeof obj[i] !== 'object' || obj[i] === null){
new_value[i] = obj[i];
}else{
new_value.push(f(obj[i]));
}
}
}else{
new_value = {};
for(let item in obj){
if(obj.hasOwnProperty(item)){
if(typeof obj[item] !== 'object' || obj[item] === null){
new_value[item] = obj[item];
}else{
Object.assign(new_value, { [item]: f(obj[item])});
}
}
}
}
}else{
new_value = obj;
}
return new_value;
}; |
我觉的你的理解有点问题,对象的赋值操作不能算是浅拷贝。在对对象进行浅拷贝时,对象中的基本数据类型会开辟新的空间,引用类型指向的还是同一个地址。而赋值操作,是将对象B的地址指向对象A。
|
我同你认知的一样啊,将引用类型直接赋值给其他变量,只是传递了内存地址。
获取 Outlook for Android<https://aka.ms/ghei36>
…________________________________
From: gudongz <[email protected]>
Sent: Wednesday, February 13, 2019 5:47:45 PM
To: Wscats/Good-Text-Share
Cc: 谭峰; Comment
Subject: Re: [Wscats/Good-Text-Share] Javascript深浅拷贝 (#57)
我觉的你的理解有点问题,对象的赋值操作不能算是浅拷贝。在对对象进行浅拷贝时,对象中的基本数据类型会开辟新的空间,引用类型指向的还是同一个地址。而赋值操作,是将对象B的地址指向对象A。
举个例子
var obj1 = { name: 'zhangsan', num: [1, 2, 3] } // 赋值操作 var obj2 = obj1 obj2.name = 'lisi' console.log(obj1) // {name: "lisi", num: [1, 2, 3] } console.log(obj2) // {name: "lisi", num: [1, 2, 3] } // 浅拷贝 var obj3 = Object.assign({}, obj1) obj3.name = 'wanger' console.log(obj1) // {name: "lisi", num: [1, 2, 3] } console.log(obj3) // {name: "wanger", num: [1, 2, 3] }
―
You are receiving this because you commented.
Reply to this email directly, view it on GitHub<#57 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AayVkmZtc8X140WL6dPazBDB1MYAYOLFks5vM99BgaJpZM4KViK->.
|
如果需要深拷贝 函数和正则 呢 |
assign不是深克隆 |
Javascript有六种基本数据类型(也就是简单数据类型),它们分别是:Undefined,Null,Boolean,Symbol,Number和String。还含有一种复杂数据类型,就是对象
注意Undefined和Null的区别,Undefined类型只有一个值,就是undefined,Null类型也只有一个值,也就是null
Undefined其实就是已声明未赋值的变量输出的结果
null其实就是一个不存在的对象的结果
简单的数据类型和复杂的数据类型有以下重要的区别
对于简单数据类型
它们值在占据了内存中固定大小的空间,并被保存在栈内存中。当一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本,还有就是不能给基本数据类型的值添加属性
上面代码中a就是简单数据类型(Number),b就是a的副本,它们两者都占有不同位置但相等的内存空间
对于复杂的数据类型
复杂的数据类型即引用类型,它的值是对象,保存在堆内存中,包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针。从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象。
我们可以看到obj赋值给obj2后,当我们更改其中一个对象的属性值,两个对象都发生了改变,究其原因局势因为obj和obj2这两个变量都指向同一个指针,赋值只是复制了指针,所以当我们改变其中一个的值就会影响另外一个变量的值
浅拷贝
其实这段代码就是浅拷贝,有时候我们只是想备份数组,但是只是简单让它赋给一个变量,改变其中一个,另外一个就紧跟着改变,但很多时候这不是我们想要的
深拷贝
数组
对于数组我们可以使用
slice()
和concat()
方法来解决上面的问题slice
concat
对象
对象我们可以定义一个新的对象并遍历新的属性上去实现深拷贝
当然我们可以封装好一个方法来处理对象的深拷贝,代码如下
The text was updated successfully, but these errors were encountered: