基礎概念
js 本身是基於面向對象開發的語言
=> 封裝 繼承 多態
封裝: 類也是一個函數,把實現一個代碼的功能進行封裝,以此實現 低耦合高內聚
多態: 重載 重寫
重寫:子類重寫父類上的方法
重載:相同的方法,由於參數或者返回值不同,具備了不同的功能。
js中的重載:同一個方法內,根據傳參不同實現不同的功能
繼承:子類繼承父類中的方法
繼承目的
讓子類的實例也具備父類中私有屬性和公共方法
1.原型鏈繼承
(讓子類的原型等於父類的實例即可)
現在來看一個例子
原型繼承特點
1.父類中私有和公有的屬性方法,最后都變為子類實例公有的。
2.原型鏈繼承並不會把父類的屬性方法‘拷貝’給子類,而是讓子類基於__proto__原型鏈找到自己定義的屬性和方法。
** 注意:**進行修改的話,會使父類的屬性和方法也會進行修改。這樣不僅會影響其他父類的實例,也影響其他子類的實例
代碼
// 繼承的目的 讓子類的實例也具備父類中私有屬性和公共方法
function Parent() {
this.x = 100;
}
Parent.prototype.getx = function getx() {
return this.x
}
function Child() {
this.y = 200
}
// 第一種方法:原型繼承(讓子類的原型等於父類的實例即可)
Child.prototype = new Parent //=> 原型繼承
Child.prototype.constructor = Child;
Child.prototype.gety = function gety () {
return this.y
}
let c1 = new Child()
// 現在c1 只能用y 和gety,但是我們也想讓c1繼承parent的方法和屬性
console.log(c1,'c1')
console.log(c1.__proto__)
console.log(c1.__proto__.__proto__.getx)
2call繼承
(只能繼承父類中私有的,不能繼承父類中公有的)
代碼
// 第二種繼承方式:call繼承(只能繼承父類中私有的,不能繼承父類中公有的)
function Parent() {
this.x = 100;
}
Parent.prototype.getx = function getx() {
return this.x
}
function Child() {
// 在子類構造函數中,把父類當做普通方法執行(沒有父類的實例,父類原型上的那些東西也就和它沒關系了)
// this -> child的實例c2
Parent.call(this) //this.x = 100 相當於強制給c2這個實例設置一個私有屬性x,屬性值為100,相當於
//讓子類實例繼承了父類的私有屬性,並且也變為了子類私有的屬性 ’拷貝式‘
this.y = 200
}
Child.prototype.gety = function gety() {
return this.y
}
let c2 = new Child()
// 現在c2 只能用y 和gety,但是我們也想讓c1繼承parent的方法和屬性
console.log(c2,'c2')
3.寄生組合繼承(call 繼承 + 另類原型繼承)
代碼
function Parent() {
this.x = 100;
}
Parent.prototype.getx = function getx() {
return this.x
}
function Child() {
Parent.call(this)
this.y = 200
}
// 第一種 用__proto__ 的方式,把child的prototype.__proto__強制改為Parent.prototype
// Child.prototype.__proto__ = Parent.prototype
// 第二種 使用Object.create 也是讓子類的實例指向父類的原型
Child.prototype = Object.create(Parent.prototype)
// 這種創建方式 會丟失constructor 我們手動給加一個
Child.prototype.constructor = Child;
Child.prototype.gety = function gety () {
return this.y
}
let c3 = new Child()
// 現在c2 只能用y 和gety,但是我們也想讓c1繼承parent的方法和屬性
console.log(c3,'c3')
4es6 中的類和繼承
代碼
class Parent1{
constructor(){
this.x = 100
}
getx(){
return this.x
}
}
//繼承 extends Paren
//注意:繼承后一定要在constructor第一行加super
class Child1 extends Parent1{
constructor(){
super(); //=>類似於我們之前的call繼承
this.y = 200
}
getx(){
return this.y
}
}
let c4 = new Child1;
console.log(c4,'c4')