今天看的《JavaScript設計模式》-作者:張容銘。主要看了js繼承。下麵我將看的,以及代碼貼出來,跟大家一起學習,分享。共同進步。 先來個簡單是 單繼承 多繼承 類繼承 是通過子類的原型prototype對父類實例化來實現的 缺點:父類中的共有屬性如果是引用類型就會在子類的所有實例中共擁有,一 ...
今天看的《JavaScript設計模式》-作者:張容銘。主要看了js繼承。下麵我將看的,以及代碼貼出來,跟大家一起學習,分享。共同進步。
先來個簡單是
單繼承
//單繼承 var extend=function(target,source){ //遍歷原對象的所有屬性 for(var i in source){ //將原對象中的屬性複製到目標對象中 target[i]=source[i]; } //返回目標對象 return target; //這是淺拷貝 }
多繼承
//多繼承 var mix=function(){ var i=1;//從第二個參數開始 var arg;//緩存arguments參數 var len=arguments.length;//參數長度 var target=arguments[0]; for(;i<len;i++){ arg=arguments[i]; //遍歷原對象的所有屬性 for(var a in arg){ //將原對象中的屬性複製到目標對象中 target[a]=arg[a]; } } //返回目標對象 return target; //這是多對象淺拷貝(data,ds,de);會把ds,de的各個屬性方法拷貝到data,不好之處,有可能ds的屬性會被de的屬性覆蓋 }
類繼承
是通過子類的原型prototype對父類實例化來實現的
缺點:父類中的共有屬性如果是引用類型就會在子類的所有實例中共擁有,一旦被某一個實例改變,則父類中的共有屬性改變。
//聲明 function SuperClass(){ //共有屬性--如果是引用類型(數組,對象)就會有問題 this.superValue=true; } //為父類添加共有方法 SuperClass.prototype.getSuperValue=function(){ return this.superValue; } //聲明子類 function SubClass(){ this.subValue=false; } //繼承父類 SubClass.prototype=new SuperClass; //為子類添加共有方法 SubClass.prototype.getSubValue=function(){ return this.subValue; } var instan=new SubClass; console.log(instan.getSuperValue()); console.log(instan.getSubValue());
構造函數繼承
在子類的構造函數作用環境中執行一次父類的構造函數來實現
缺點:父類原型無法被繼承,是通過call改變函數作用域實現的
//聲明 function SuperClass(id){ //共有屬性--如果是引用類型(數組,對象)就會有問題 this.books=["a","b","c"]; this.id=id; } //為父類添加共有方法 SuperClass.prototype.showbooks=function(){ console.log(this.books); } //聲明子類 function SubClass(id){ SuperClass.call(this,id); } //為子類添加共有方法 SubClass.prototype.conso=function(){ console.log("SubClass"); } var instace1=new SubClass(10); var instace2=new SubClass(11); instace1.books.push("d"); console.log(instace1.books); console.log(instace1.id); console.log(instace2.books); console.log(instace2.id); console.log(instace2.showbooks);//父類原型無法被繼承
組合式繼承
把類繼承與構造函數組合起來。
缺點:父類構造函數執行兩遍
//聲明 function SuperClass(id){ //共有屬性--如果是引用類型(數組,對象)就會有問題 this.books=["a","b","c"]; this.id=id; } //為父類添加共有方法 SuperClass.prototype.showbooks=function(){ console.log(this.books); } //聲明子類 function SubClass(id,name){ SuperClass.call(this,id); this.name=name; } //類式繼承 子類原型繼承父類 SubClass.prototype=new SuperClass(); //為子類添加共有方法 SubClass.prototype.getName=function(){ console.log(this.name); } var instace1=new SubClass(10,"SubClass10"); var instace2=new SubClass(11,"SubClass11"); instace1.books.push("d"); console.log(instace1.books); console.log(instace1.id); console.log(instace1.getName()); console.log(instace2.books); console.log(instace2.id); console.log(instace2.getName());
原型式繼承
對類繼承進行封裝,過渡對象相當於類繼承的子類,只不過在原型式中作為過渡對象出現。
缺點:類繼承的缺點
//原型式繼承 function createObj(o){ //聲明一個過渡對象 function F(){}; //過渡對象原型繼承o F.prototype=o; //返回一個新的過渡對象實例 return new F(); } var obj={ name:"js book", alickbooks:["css book","html book"] } var book_a=createObj(obj); book_a.name="book_a"; book_a.alickbooks.push("book_a"); console.log(book_a.alickbooks); var book_b=createObj(obj); book_b.name="book_b"; book_b.alickbooks.push("book_b"); console.log(book_a.alickbooks);
寄生式繼承
就是對原型式繼承的第二次封裝,並且在這第二次封裝的時候對繼承的對象進行擴展,
這樣新創建的對象不僅有父類的屬性方法也有自己擴展的屬性與方法。
缺點:類繼承的缺點
//寄生式繼承 function createObj(o){ //聲明一個過渡對象 function F(){}; //過渡對象原型繼承o F.prototype=o; //返回一個新的過渡對象實例 return new F(); } var obj={ name:"js book", alickbooks:["css book","html book"] } function createBook(obj){ //通過原型繼承方式創建對象 var o=new createObj(obj);//這個new要與不要是一樣的 //拓展新方法 o.getname=function(){ console.log(name); } //返回拓展後的新對象 return o; } var book_a=createBook(obj); book_a.name="book_a"; book_a.alickbooks.push("book_a"); console.log(book_a.alickbooks); var book_b=createBook(obj); book_b.name="book_b"; book_b.alickbooks.push("book_b"); console.log(book_a.alickbooks);
寄生組合式繼承
//寄生式繼承 function createObj(o){ //聲明一個過渡對象 function F(){}; //過渡對象原型繼承o F.prototype = o; //返回一個新的過渡對象實例 return new F(); } // // 寄生式繼承 繼承原型 // 傳遞參數 subClass 子類 // 傳遞參數 superClass 父類 // function inheritPrototype(subClass,superClass){ //複製一份父類的原型副本保存在變數中 var p = createObj(superClass.prototype); //修正因為重寫子類原型導致子類的constructor; p.constructor = subClass; //設置子類的原型 subClass.prototype=p; } //定義父類 function SuperClass(name){ //共有屬性 this.colors = ["red","blue","green"]; this.name = name; } //為父類添加共有方法 SuperClass.prototype.getName = function(){ console.log(this.name); } //定義子類 function SubClass(name,time){ //構造函數式繼承 SuperClass.call(this,name); //子類新增屬性 this.time = time; } //寄生式繼承父類原型 inheritPrototype(SubClass,SuperClass); //子類原型新增原型方法 SubClass.prototype.getTime = function(){ console.log(this.time); }; //創建兩個測試方法 var instace1 = new SubClass("js book",2014); var instace2 = new SubClass("css book",2013); instace1.colors.push("black"); console.log(instace1.colors); console.log(instace2.colors); console.log(instace1.getTime()); console.log(instace2.getTime()); console.log(instace1.getName()); console.log(instace2.getName());
總結:這篇文章是參考學習的,所有呢,代碼中都有註釋,希望能夠對大家有用。也同時希望大家在休息之餘不要忘記學習。