JS中的多種繼承方式(第12天)
//----------------JS中的多種繼承方式------------------
/*
* JS本身是基於物件導向開發的程式語言
=> 類:封裝、繼承、多型
封裝:類也是一個函式,把實現一個功能的程式碼進行封裝,以此實現“低耦合,高內聚”
多型:過載、重寫
=>過載:相同的方法名,由於引數型別/個數或者方法返回的值不同,具備了不同的功能(JS不具備嚴格意義上的過載,JS中的過載:同一個方法內,根據傳參的不同實現不同的功能)
=>重寫:子類重寫父類上的方法(伴隨著繼承執行的)
繼承:子類繼承父類中的方法
繼承的目的:讓子類的例項同時也具備父類中的私有屬性和公共的方法
*/
function Father() {
this.father_name = 'father';
this.sum = function(){
console.log(11);
}
}
Father.prototype.getName = function(){
console.log(this.name);
}
function Son(){
this.name = 'son';
}
/*
// 原型鏈繼承:讓子類的原型指向父類的例項
Son.prototype = new Father;
// 重定向原型之後記得手動補上 constructor
Son.prototype.constructor = Son;
// 原型鏈繼特點:
// 1、父類中私有的屬性和方法最後都變成了子類例項共有的
// 2、原型繼承並不是把父類的屬性和方法“拷貝”給子類,而是讓子類例項基於__proto__原型鏈查詢到父類和子類定義的屬性和方法
// 3、子類例項基於__proto__修改子類原型上的內容,只會對子類的其他例項造成影響,並不會影響父類的例項,但是如果是修改子類原型的原型鏈中的內容(即 子類例項.__proto__.__proto__),這樣修改的是父類的原型,那受影響的不僅是父類的例項,子類的其他例項也會受影響
*/
/*
// call繼承(也叫借用建構函式繼承):在子類中將父類作為普通函式執行,同時將父類中的this改為子類的例項
function Son(){
// 在子類的建構函式中把父類當做普通函式執行,將函式中的this改為子類的例項
Father.call(this);// 改變Father中的this指向
this.name = 'son';
}
// call繼承的特點:
// 1、子類只能繼承父類中私有的屬性和方法,不能繼承父類原型上的屬性和方法
// 2、子類繼承過來的屬性也變成了子類私有的
*/
// 組合繼承:原型繼承 + call繼承
/* function Son(){
Father.call(this);
this.sonName = 'son';
}
Son.prototype = new Father;
Son.prototype.constructor = Son;
// 組合繼承的特點:
// 1、子類繼承父類的私有屬性變成自己的私有屬性,繼承公有屬性和方法變成子類公有的
// 2、父類私有的屬性和方法也會繼承(拷貝)在子類的公有屬性和方法中
// console.log(f.sum === f.__proto__.sum); // false
// !注意:這種方式會把父類的私有屬性和方法同時拷貝給子類的私有和公有,且子類繼承過來的私有和公用方法不是同一個(堆地址不同)
// => 子類例項.私有方法(從父類繼承過來的) !== 子類例項.__proto__.方法(從父類繼承過來的)
*/
/* // 寄生組合繼承:在組合繼承的方法上進行改進
function Son(){
Father.call(this);
this.sonName = 'son';
}
// Object.create(protoObj):建立一個空的物件,讓這個空物件的__proto__指向 protoObj
Son.prototype = Object.create(Father.prototype);
Son.prototype.constructor = Son; */
/* // Object.create 的實現
Object.create = function(proto){
function anmouse(){}
anmouse.prototype = proto
return new anmouse;
}
console.log(Object.create(Son)) */
Son.prototype.getSonName = function(){
console.log(this.name)
}
let f = new Son;
let p = new Son;
// ---------- ES6中的類的繼承-------------
class Person{
constructor(name) {
this.person = name;
}
// 用等號的是設定私有的方法
sum = function(){
console.log(222)
}
// 直接寫的是設定公有的方法
getPerson(){
console.log(111)
}
}
// 繼承:子類 extends 父類(類似於寄生組合繼承)
class Per extends Person{
constructor(age) {
super('我是父類'); // !在子類的constructor第一行一定要加 super()
this.age = age;
}
}
let y = new Person('父類');
let q = new Per(12);