類的繼承圖解

好想吃涼皮發表於2018-04-06

#類 以前就是建構函式

繼承

先宣告兩個類,並在父類上追加一個smock方法

function Parent() {

}
Parent.prototype.smock = function () {
    console.log('吸菸');
}
function Child() {

}複製程式碼

然後讓Child的原型指向Parent的例項,這樣child例項上就有了Parent的方法了

function Parent() {  
this.name = 'hahah'  
}  
Parent.prototype.smock = function () {  
    console.log('吸菸');  
}  
function Child() {  

}  
Child.prototype = new Parent;  
let child = new Child;  
child.smock() 
}
Parent.prototype.smock = function () {
 console.log('吸菸');
}
function Child() {}
Child.prototype = new Parent;
let child = new Child;child.smock()
複製程式碼



執行結果就是“吸菸”;

執行原理如圖所示:Child類分配一個原型空間prototype,每個prototype都有constrcutor區域,new Child得到的是一個child的例項,例項上有__proto__屬性,child.__proto__指向的就是Child.prototype;同理Parent也是這樣。現在

Child.prototype = new Parent;複製程式碼

我讓Child類上的prototype等於了new出的Parent例項,也就是parent(就是上面那條1藍色線),那麼child上就有了parent上面的公有屬性和私有屬性了,那麼執行child.smock()就是得到想要的結果了。

類的繼承圖解

我們還可以驗證一下

console.log(child.__proto__.__proto__ == Parent.prototype);複製程式碼

驗證結果為true

我們也可以看一下constructor指向誰

console.log(child.constructor);複製程式碼

繼承Object.create

Object.create只繼承公有方法。

Child.prototype = Object.create(Parent.prototype);
let child = new Child;複製程式碼

但是child上面沒有name(私有屬性),但是有smock方法(公有)

怎麼實現的呢:

function create(pa) {
    function Fn() {    } //相當於構建一個類,類的原型指向父類的原型
    Fn.prototype = pa;
    return new Fn
}
//兒子查詢時,可以查詢到父類的原型,所以可以拿到父類的公有方法
Child.prototype = create(Parent.prototype);
let child = new Child;
child.smock()複製程式碼

流程圖如下:(黃色線部分:create的方法就是改變了Child的prototype的指向。)

類的繼承圖解

而此時child的constructor是Parent,要是想讓它變回Child

function create(pa,paranm) {
    function Fn() {    } //相當於構建一個類,類的原型指向父類的原型
    Fn.prototype = pa;
    let fn =  new Fn;
    fn.constructor = param.constructor.value;
    return fn
}
//兒子查詢時,可以查詢到父類的原型,所以可以拿到父類的公有方法
Child.prototype = create(Parent.prototype,{constructor:{value:Child}});
// Child.prototype = Object.create(Parent.prototype,{constructor:{value:Child}});
let child = new Child;複製程式碼

如果想繼承靜態屬性可以這樣做

Child.__proto__ = Parent複製程式碼

定義屬性

defineProperty

let obj  = {};
Object.defineProperty(obj,'a',{
    enumerable:true,//是否可列舉
    configurable:true,//可配置
   // writable:true,//是否可修改 但是不能跟get,set同在,否則會報錯
    set(val){
        console.log(val);
    },
    get(){
        console.log(100)
    },
   // value:11
})
console.log(obj.a)複製程式碼

es6的繼承

extends能繼承私有屬性

class  Parent{
    constructor(name){
        this.name = name
    }
    getnaem(){
        return  this.name
    }
}
class Child extends Parent {
複製程式碼
constructor(name,age){
        super(name)//子類有建構函式必須使用super 類似於call(this,name)
        this.age = age
    }複製程式碼

}let child = new Child('ww',9);console.log(child.name)

name 是可以拿到的,getname也能拿到(公有私有都能拿到)

靜態方法通過類來呼叫

class  Parent{
    constructor(name){
        this.name = name
    }
    getname() {
        return this.name
    }
    //通過類來繼承
    static fu(){
        return 100
    }
}
Parent.fn()複製程式碼


相關文章