1. 程式人生 > >JavaScript面向物件之繼承(下)

JavaScript面向物件之繼承(下)

原型式繼承

這種繼承方式沒有使用嚴格意義上的建構函式,藉助原型還可以基於已有的物件建立新物件,同時還不必因此建立自定義型別

function object(o) {
    function Fun() {}
    Fun.prototype = o;
    return new Fun();
}

在object函式內部,先建立一個臨時性的建構函式Fun,然後將傳入的物件作為這個建構函式的原型,最後返回這個臨時型別的一個新例項。
本質上來說,object對傳入其中的物件執行了一次淺複製。

function object(o) {
function Fun() {
} Fun.prototype = o return new Fun() } const Person = { name: "姓名", hobby: ["旅遊","電影"] } const LJJ = object(Person) LJJ.name = "劉家軍" LJJ.hobby.push("敲程式碼") const YH = object(Person) YH.name = "袁姮" YH.hobby.push("購物") console.log(LJJ); console.log(YH); console.log(Person);

輸出:
在這裡插入圖片描述
ES5新增Object.create規範了原型式繼承

Object.create

Object.create()這個方法我在寫js原型和原型鏈時簡單介紹過了,如果還有什麼不瞭解檢視js權威文件MDN(Object.create)
看下面三種建立物件的方法

console.log(Object.create(null))
console.log(new Object())
console.log({})

輸出:
在這裡插入圖片描述
可以看出第一種建立方法最乾淨;
我們繼續看程式碼:

const Person = {
    name: "姓名",
    hobby: ["旅遊","看電影"]
};
const LJJ = Object.create
(Person, { private : { value: "私有的", // private 屬性值 writable:true // 屬性可寫 } }); LJJ.name = "劉家軍" LJJ.hobby.push("唱歌") LJJ.private = "敲程式碼" console.log(LJJ.private) // 敲程式碼 //-------------------------------------- const Person = { name: "姓名", hobby: ["旅遊","看電影"] }; const YH = Object.create(Person, { private : { value: "私有的", // private 屬性值 writable: false // 屬性不可寫 } }); YH.name = "袁姮" YH.hobby.push("美食") YH.private = "購物" console.log(YH.private) // 私有的

private 的屬性還有很多 詳細請看js權威文件 MDN

區別

1.Object.cerate()繼承指定物件
2.new Object() 繼承內建物件Object
3.可以通過Object.create(null) 建立一個乾淨的物件,也就是沒有原型,而 new Object() 建立的物件是 Object的例項,原型永遠指向Object.prototype。

寄生式繼承

寄生式繼承是與原型式繼承緊密相關的一種思路,它創造一個僅用於封裝繼承過程的函式,在函式內部以某種方式增強物件,最後再返回物件。

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

function clone(params) {
    const proto= object(params) //通過呼叫函式建立一個新物件
    return proto
}
const Person = {
    name: "姓名",
    hobby: ["旅遊","看電影"]
}
const LJJ = clone(Person);
LJJ.name = "劉家軍"
LJJ.hobby.push("敲程式碼")
console.log(LJJ)

輸出:
在這裡插入圖片描述
寄生式繼承和原型式繼承,方法接近

寄生組合式繼承

組合繼承有個弊端就是會呼叫兩次被繼承者的建構函式,解決方法就是使用寄生組合式繼承。這又是什麼呢?這個相對之前的比較複雜,但是高效的一點是隻呼叫一次被繼承者建構函式,原理就是通過寄生方式建立一個被繼承者的副本,副本和被繼承者共用一個prototype,這樣就解決了之前的問題

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}
function clone(Children, Person) {
    const proto = object(Person.prototype) // 返回Person的一個副本
    proto.constructor= Children // 設定constructor指向, 因為新副本的原型物件被重寫
    Children.prototype = proto // 副本作為Children的原型物件
}

function Person() {
    this.name = "姓名"
}
Person.prototype.sayName = function() {
console.log(this.name)
}
function Ljj() {
    Person.call(this)
    this.name = "劉家軍"
}

function Yh() {
    Person.call(this)
    this.name = "袁姮"
}
clone(Ljj, Person)
clone(Yh, Person)
const LJJ = new Ljj()
const YH = new Yh()
LJJ.sayName() // 劉家軍
YH.sayName() // 袁姮