当我们操作两个对象的时候
1.0 赋值
var obj = {
age: 123,
name : 'mike',
son : {
age : 18,
name : 'peter'
}
}
var newObj = obj;
newObj.name = 'kaisa';
console.log(obj);
赋值操作,两个变量指向同一个地址,
除非 newObj = newnewObj,
否则 obj和 newObj是互相影响的.
我们也可以看成 数据的流向是双向的.
我们有时希望这样,
但有时我们也希望能毫无关系.互不影响.
2.0深度克隆
function clone (origin, target) {
var target = target || {};
for(var key in origin){
if(origin[key] !== null && origin.hasOwnProperty(key)){
if(typeof(origin[key]) == 'object'){
console.log(origin.hasOwnProperty(key),key);
if(Object.prototype.toString.call(origin[key]) == '[object Array]'){
target[key] = [];
}else{
target[key] = {};
}
clone(origin[key],target[key]);
}else {
target[key] = origin[key];
}
}
}
return target;
}
var newObj = [];
clone(obj,newObj);
console.log(newObj);
newObj.name = 'kaisa';
console.log(obj);
console.log(newObj);
你发现,两个对象一样,但互不影响.
但我们知道一个对象不只是他自己,还包括他的原型链
3.0 对象间继承
最简单的是这样
function Obj () {}
var obj = new Obj();
var newObj = Object.create(obj);
这样就能继承obj以及obj上的原型链
或者其实1.0版本赋值也可以做到,因为本质上是同一个对象.
那我们有没有办法深度克隆的同时,还能继承?
最简单的方法是
var newObj = new Obj()
这样的话,出来的基本上一样,又能继承.
那我们就想克隆obj的同时,想要继承呢?
也许可以
var newObj = Object.create(obj);
然后调用2.0
clone(obj,newObj);
Person.prototype.name = 'mike';
Person.prototype.aaa = 'bbb';
function Person () {
}
var obj = new Person();
obj.age = 18;
obj.son = {
name : 'peter',
age : 5
}
var newObj = Object.create(obj);
clone(obj,newObj);
console.log(newObj);
newObj.age = 99;
console.log(obj);
console.log(newObj);
console.log(obj.name);
console.log(newObj.name);//竟然可以
我本来以为不可以,后来发现,clone函数里从头到尾都没有对 target = 赋值,所以target地址是没有变化的,所以可以继承.这就把我给逗乐了.
既然如此,能不能把两个步骤写在一起?
4.0 继承版深度克隆
Person.prototype.name = 'mike';
function Person () {
}
var obj = new Person();
obj.age = 18;
obj.son = {
name : 'peter',
age : 5
}
function clone (origin,target,flag) {
if(!flag){
var target = Object.create(origin);
flag = true;
}else{
var target = target;
}
for(var key in origin){
if(origin[key] !== null && origin.hasOwnProperty(key)){
if(typeof(origin[key]) == 'object'){
if(Object.prototype.toString.call(origin[key]) == '[object Array]'){
target[key] = [];
}else{
target[key] = {};
}
clone(origin[key],target[key],flag);
}else {
target[key] = origin[key];
}
}
}
return target;
}
var newObj = clone(obj,newObj);
console.log(newObj);
newObj.age = 99;
console.log(obj);
console.log(newObj);
console.log(obj.name);
console.log(newObj.name);
但这个版本有个问题, 那就是 必须要接收返回值,newobj = clone(obj,newObj);//括号里的newOjb实际上不用传,因为不会起效果
最近看学习q源码
有个extend继承跟本篇内容有很大的相关性
jq extend 源码笔记 https://www.jianshu.com/p/6d033fa5c39e