標籤:屬性 對象 核心 eof htm 遞迴調用 extend 執行個體 不同的
普通對象的繼承方法
今天有個朋友給問我 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); //a12 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);// a13 14 obj2.name = ‘b‘; //改變屬性15 obj2.age = 18 ; //給obj2添加一個屬性16 17 console.log(obj1.name+‘ ‘+obj1.age); //a undefined18 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 = {}; //聲明一個Null 物件 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)// a14 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); //xiaoming23 console.log(obj2.person.name);//xiaohong
普通對象如何繼承?