普通对象如何继承?
普通对象的继承方法
今天有个朋友给问我 var obj1 = {},var obj2 = obj1,如何能做到改变obj2的属性值而obj1里面的值。
大家都知道,这方法涉及到了对象的引用,使用的是同一块内存,所以呢就会你变我也变。说到这里很明显,我们需要重新申请一块地方来放obj2的东西,我就说继承和new,那么下面我来说说 普通对象是如何做到继承
方法一:单一属性继承 , 普通对象赋值实现继承
1 var obj1 = { 2 name :'a', 3 }; 4 var obj2 = { 5 name : obj1.name, 6 }; 7 8 console.log(obj2.name); //a 9 obj2.name = 'b'; 10 11 console.log(obj1.name); //a 12 console.log(obj2.name); //b
方法二:利用构造函数原型继承
1 var obj1 = { 2 'name' :'a' 3 } 4 //继承函数 5 function extend(obj){ 6 function Fn(){};//创建构造函数 7 Fn.prototype = obj; //把被继承的对象赋值给Fn的prototype 8 return new Fn();//返回值是 实例化Fn 9 } 10 var obj2 = extend(obj1); //相当于var obj2 = new Fn(); 11 12 console.log(obj2.name);// a 13 14 obj2.name = 'b'; //改变属性 15 obj2.age = 18 ; //给obj2添加一个属性 16 17 console.log(obj1.name+' '+obj1.age); //a undefined 18 console.log(obj2.name+' '+ obj2.age); //b 18
方法三:浅拷贝 --核心for in ,在之前的 “jq的extend” 方法中提到这个概念,只说到了使用方法,现在来说模拟一下实现原理
很明显,之前一样,如果obj1的name 属性是一个对象或者数组那么,此时继承仅仅是一个地址,比如有个属性 person:{name:'aa',age:18},那么当obj2或者obj1去改变
里面的name 或者是 age的时候 ,则obj1和obj2都会发生改变。详细请看:http://www.cnblogs.com/NTWang/p/6175773.html
1 var obj1 = { 2 'name' :'a', 3 } 4 function extend(obj){ 5 var obj2 = {}; //声明一个空对象 6 for(var i in obj){ 7 obj2[i] = obj[i]; //循环赋值 8 } 9 return obj2; 10 } 11 var obj2 = extend(obj1);//函数执行并赋值给变量 12 13 console.log(obj2.name)// a 14 obj2.name = 'b'; 15 16 console.log(obj1.name);//a 17 console.log(obj2.name);//b
方法四:深拷贝,完善浅拷贝,两种方法适用不同的需求,它的实现原理是:递归调用浅拷贝方法
1 var obj1 = { 2 person:{name:'xiaoming',age:18} 3 } 4 5 function deepCopy(obj){ 6 //判断obj 是是否是对象,不是则直接return 7 if (typeof obj != 'object') { 8 return obj; 9 } 10 var obj2 = {};//声明一个对象 11 12 for(var i in obj){ 13 obj2[i] = deepCopy(obj[i]);//调用自己 14 } 15 return obj2; 16 } 17 18 var obj2 = deepCopy(obj1); 19 20 obj2.person.name = 'xiaohong'; 21 22 console.log(obj1.person.name); //xiaoming 23 console.log(obj2.person.name);//xiaohong