Object.create()和setPrototypeof和Child.prototype = Parent.prototype和Child.prototype = new Parent()的區別

 

Child.prototype = Parent.prototype和Child.prototype = new Parent()的區別

## 一、Child.prototype = new Parent()取不到Child原型上的屬性,constructor指向Parent 修正:Child.prototype = new Parent() 會致使Child多個實例指向同一個引用,由於new Parent返回的是一個引用類型,此時修改Child的某個實例的屬性,
其它實例的屬性也會被修改。
//
父類 function Parent(){ this.name = "P_Name"; } Parent.prototype.func=function(){ console.log("Parent Func"); } //子類 function Child(){ } Child.prototype=new Parent(); Child.prototype.func = function(){ console.log("Child Func"); } var child = new Child; var parent = new Parent; child.func();//Child Func console.log(child.name);//P_Name console.log(Child.prototype.constructor) // Parent parent.func();//Parent Func ## 二、Child.prototype = Parent.prototype取不到Parent的構造函數屬性,constructor指向Parent,並且對子類的原型方法重寫會使父類的原型方法被重寫 function Child2(){ } # 如下賦值將覆蓋Parent.prototype.func方法 Child2.prototype=Parent.prototype; Child2.prototype.func = function(){ console.log("Child2 Func"); } var child2 = new Child2; child2.func();//Child2 Func console.log(child2.name);//undefined console.log(Child2.prototype.constructor) // Parent parent.func();//Child2 Func

setPrototypeOf 與 Object.create區別

 

能夠用prototype訪問的只有function類型,其餘類型只能用getPrototypeOf或者proto,其餘類型也都是經過function生成的(String,Number……涉及到隱式建立對象)xss

對象的原型只是一個引用,指向另一個對象。對象原型之間的嵌套組成了原型鏈,原型鏈的做用是維護訪問對象屬性的查詢,肯定訪問權限。函數

 

若存在A和B倆個函數,讓A的原型指向B

1.setPrortotypeOf

Object.setPrototypeOf(A.prototype,B.prototype)this

2.Create

A.prototype = Object.create(B.prototype)spa

倆者均可以達到設置對象原型的功能,可是具體表現上有一些區別。

代碼以下

function Animal (name,sound) {
        this.name = name
        this.sound = sound
    }
    
    Animal.prototype.shout = function () {
        console.log(this.name + this.sound)
    }
    
    let dog = new Animal('pipi','wang!wang!')
    
    // 定義Plants
    function Plants (name) {
        this.name = name
        this.sound = null
    }
    
    // 函數接收參數用於區分
    Plants.prototype.shout = function (xssss) {
        console.log(this.name + this.sound +'plants tag')
    }
    
    Plants.prototype.genO2 = function () {
        console.log(this.name + '生成氧氣。')
    }

使用Object.create

 Animal.prototype = Object.create(Plants.prototype)
    console.log(Animal.prototype)
    /*
    Plants {}
        __proto__:
            shout: ƒ (xssss)
            genO2: ƒ ()
            constructor: ƒ Plants()
            __proto__: Object
    */
    let cat = new Animal('mimi','miao~miao~')
    
    dog.shout() // pipi wang!wang!
    cat.shout() // mimi miao~miao~ plants tag
    cat.genO2() // mimi 生成氧氣。

使用setPrototypeOf

   Object.setPrototypeOf(Animal.prototype,Plants.prototype)
    console.log(Animal.prototype)
    /*
    Plants {shout: ƒ, constructor: ƒ}
        shout: ƒ (xssss)
        constructor: ƒ Animal(name,sound)
        __proto__:
        shout: ƒ ()
        genO2: ƒ ()
        constructor: ƒ Plants()
        __proto__: Object
    */
    dog.shout() // pipi wang!wang!
    cat.shout() // mimi miao~miao~
    cat.genO2() // mimi 生成氧氣。

總結

使用Object.create,Animal.prototype將會指向一個空對象,空對象的原型屬性指向Plants的prototytpe。因此咱們不能再訪問Animal的原有prototypoe中的屬性。Object.create的使用方式也凸顯了直接從新賦值。prototype

使用Object.setPrototypeOf則會將Animal.prototype將會指向Animal原有的prototype,而後這個prototype的prototype再指向Plants的prototytpe。因此咱們優先訪問的Animal,而後再是plants。code

在進行倆個原型之間的委託時使用setPrototype更好,Object.create更適和直接對一個無原生原型的對象快速進行委託。對象

相關文章
相關標籤/搜索