js函式的物件的繼承
阿新 • • 發佈:2020-08-13
1.原型鏈繼承:將父親的例項賦給子類的原型。
缺點:如果有一個子類例項改變所繼承的內容,則當下一個子類例項繼承是會是上一個子類改變之後的內容,而不是原有父親的內容。
(解決:物件冒充繼承方法)
function Father(name, age) { this.name = 'li'; this.age = 3; this.arr = [1, 2, 3]; } function Son(sex) { this.sex = sex; } Son.prototype= new Father; //將父類的例項賦值給子類的原型 var son1 = new Son('男'); //new一個子類的例項son1 var son2 = new Son('女'); //new一個子類的例項son2 console.log(son1.arr); //列印son1繼承的屬性arr [1, 2, 3] son1.arr.push(4); //通過son1改變arr的值 此時改變的是子類的原型鏈 console.log(son2.arr); //再用son2列印arr值 [1, 2, 3, 4]
優點: 解決了原型鏈繼承引用型別共用的問題 。
缺點:不能呼叫父類原型鏈中的方法函式。(解決:組合模式方法)
function Father(name, age) { this.name = 'li'; this.age = 3; this.arr = [1, 2, 3]; this.sayHi = function() { return 'Hi' + this.name; } } Father.prototype.showName= function() { return this.name; } function Son(sex) { Father.call(this); //通過call改變Father的this指向Son,這樣就可以使Son中擁有Father的屬性 this.sex = sex; } var son1 = new Son('男'); console.log(son1); //Son{nme: "li", age: 3, arr: Array(3), sex: "男", sayHi: ƒ} console.log(son1.name); //li console.log(son1.sayHi()); //可以呼叫父類本身具有的方法 Hili // console.log(son1.showName()); //報錯 son1.showName is not a function //缺點:不能呼叫父類原型鏈中的方法函式 //---------------------------------------------------------- //解決了原型鏈中一個子類物件改變父類屬性會影響其他子類的問題 son1.arr.push(4); console.log(son1.arr); //[1, 2, 3, 4] var son2 = new Son(); console.log(son2.arr); //[1, 2, 3]
優點:解決了不能呼叫父類原型鏈中的方法函式;
缺點: 1.相同的屬性,在原型鏈上出現了兩次(讀取沒有問題,因為子例項上面的屏閉了 原型上面的屬性)
2.父類的建構函式呼叫了兩次
解決:寄生組合繼承
function Father(name, age) { this.name = 'li'; this.age = 3; this.arr = [1, 2, 3]; this.sayHi = function() { return 'Hi' + this.name; } } Father.prototype.showName = function() { return this.name; } function Son(sex) { Father.call(this); //通過call改變Father的this指向Son,這樣就可以使Son中擁有Father的屬性 呼叫一次 this.sex = sex; } Son.prototype = new Father(); //通過原型鏈繼承父類原型中的方法 呼叫兩次 var son1 = new Son('男'); console.log(son1); //Son{name: "li", age: 3, arr: Array(3), sex: "男", sayHi: ƒ} console.log(son1.showName()); //li console.log(son1.sayHi()); //Hili
可以看到age,arr,name,sayHi在原型鏈中出現了兩次。
function Father(name, age) { this.name = 'li'; this.age = 3; this.arr = [1, 2, 3]; this.sayHi = function() { return 'Hi' + this.name; } } Father.prototype.showName = function() { return this.name; } // Son.prototype = new Father;//不能直接繼承父類 // 父的例項,不能直接賦給子的原型,利用一箇中間函式中轉一下 function Son(sex) { Father.call(this); // 利用物件冒充繼承繼承屬性Father的屬性 this.sex = sex; } // var F = function() {}; // F.prototype = Father.prototype; // Son.prototype = new F(); // Son.prototype.constructor = Son; inherits(Son, Father); // 調這個封裝函式,相當於上面四句話 // 子的原型上的方法,必須在呼叫inherits以後,再新增 var son1 = new Son('男'); console.log(son1.showName()); //li function inherits(Child, Parent) { var F = function() {}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; }