1.原型模式 function Father(){ this.property = true; } Father.prototype.getValue = function(){ return this.property; } function Son(){ this.Sonproperty = f ...
1.原型模式
function Father(){ this.property = true;} Father.prototype.getValue = function(){
return this.property; } function Son(){ this.Sonproperty = false; } //繼承Father Son.prototype = new Father();//原型重寫,contructor被改寫 Son.prototype.construtor = Son;//重新指向Son Son.prototype.getSonValue = function(){ return this.property; } var instance = new Son(); console.log(instance.getValue()); /*缺點: 1.引用原型值會被所有實例共用 2.子類無法向父類傳參 */ 2.借用函數繼承(經典繼承) //基本思想:在子類型構造函數中調用超類型的構造函數 function Father(){ this.colors = ["red","blue","green"]; name = "haha"; }
function Son(){ Father.call(this);//繼承Father,並向父類型傳參
} Son.prototype = new Father; var instance1 = new Son(); instance1.colors.push("black"); console.log(instance1.colors);
instance2 = new Son(); instance2.colors.push("pink"); console.log(instance2.colors); /* 解決了原型鏈所存在的兩個問題 但是依然存在構造函數方法無法復用的問題 */
3.組合繼承(偽經典繼承)---經常使用 // //集合原型和構造兩者之長 // //基本思想: 使用原型鏈實現對原型屬性和方法的繼承,通過借用構造函數來實現對實例屬性的繼承. function Father(name){ this.name = name; this.colors = ["red","pink","green"]; }
Father.prototype.sayname = function(){ console.log(this.name); }
function Son(name,age){ Father.call(this,name);//使用構造函數進行實例屬性的繼承 this.age = age; }
Son.prototype = new Father();//使用原型鏈繼承超類型方法 Son.prototype.constructor = Son;//重新指向Son Son.prototype.sayage = function(){ console.log(this.age); }
var instance1 = new Son("lisi",12); instance1.colors.push("brown"); console.log(instance1.colors); instance1.sayname(); instance1.sayage();
var instance2 = new Son("hah",22); instance2.colors.push("black"); console.log(instance2.colors); instance2.sayname(); instance2.sayage();
4.原型式繼承(淺拷貝)
//原型式繼承 /*基本思想:在object()函數內部, 先創建一個臨時性的構造函數, 然後將傳入的對象作為這個構造函數的原型,最後返回了這個臨時類型 的一個新實例.*/ var person = { name : "van", friends : ["hah","yisi"] }; var anotherPerson = Object.create(person); anotherPerson.friends.push("yixiu"); console.log(person.friends); /* 和原型模式相同的是所有新對象依然共用含有引用類型值的屬性 */ 5.寄生式繼承 /*寄生式繼承的思路與(寄生)構造函數和工廠模式類似, 即創建一個僅用於封裝繼承過程的函數,該函數在內部以 某種方式來增強對象,最後再像真的是它做了所有工作一樣返回對象.*/ function createAnother(original){ var clone = Object.create(original);//先進行淺複製後增強對象 clone.sayhi = function(){//進行增強 console.log(1); } return clone; } var person = { friends : ["hah","yisi"] }; //缺點:無法進行函數復用,只能使用父類中的方法 // person.prototype.say = function(){ // console.log(2); // } var anotherPerson = createAnother(person); anotherPerson.friends.push("yixiu"); console.log(person.friends); anotherPerson.sayhi(); // anotherPerson.say(); 6.寄生組合式繼承(結合前面的所有優點) //寄生組合式繼承就是為了降低調用父類構造函數的開銷而出現的 //基本思路是: 不必為了指定子類型的原型而調用超類型的構造函數 function extend(subClass,superClass){ var F = function(){}; F.prototype = superClass.prototype; //subClass.prototype =superClass.prtotype相當於原型共用而非繼承 subClass.prototype = new F();//繼承superClass的原型 subClass.prototype.constructor = subClass;//原型重寫,手動綁定subClass.superclass = superClass.prototype;//將superClass.prototype緩存起來,方便後續訪問 if(superClass.prototype.constructor == Object.prototype.constructor){ superClass.prototype.constructor = superClass; } } function Father(name){ this.name = name; this.colors = ["red","pink","green"]; }
Father.prototype.sayname = function(){ console.log(this.name); }
function Son(name,age){ Father.call(this,name);//使用構造函數進行實例屬性的繼承,調用第一次 this.age = age; }
extend(Son,Father);// Son.prototype.constructor = Son;//重新指向Son Son.prototype.sayage = function(){ console.log(this.age); }
var instance1 = new Son("lisi",12); instance1.colors.push("brown"); console.log(instance1.colors); instance1.sayname(); instance1.sayage();
var instance2 = new Son("hah",22); instance2.colors.push("black"); console.log(instance2.colors); instance2.sayname(); instance2.sayage();