javascript中的類,繼承,構造函數詳解

前言

在es5中實現一個構造函數,並用new調用,即可得到一個類的實例。到瞭es6發佈瞭Class的寫法,js的面向對象變成也變得比較規范瞭。聊到類就不能不說類的構造函數以及類如何繼承

一、Class類

定義一個類:

    class A {
        constructor(name){
            this.name = name
        }
        getName(){
            return this.name
        }
    }
    var newA = new A("A")
    console.log(newA.getName())  // A

二、es5構造函數

在es5中沒有Class的寫法,想要實現一個類的寫法是這樣的:

    class A {
        constructor(name){
            this.name = name
        }
        getName(){
            return this.name
        }
    }
    var newA = new A("A")
    console.log(newA.getName())  // A

三、實例、類的關系

實例的原型指向類的原型

console.log(newA.__proto__ === A.prototype)  // true

關於這個可以瞭解一下實例化的過程究竟發生瞭什麼,查看MDN的連接:new操作符

  • 創建一個空的簡單JavaScript對象(即{});
  • 為步驟1新創建的對象添加屬性__proto__,將該屬性鏈接至構造函數的原型對象 ;
  • 將步驟1新創建的對象作為this的上下文 ;
  • 如果該函數沒有返回對象,則返回this。

Constructor

    console.log(A.prototype.constructor) // Class A

所有的對象都會從原型上繼承一個constructor屬性,是對函數本身的引用,也就是說指向函數本身。

這裡實例newA的原型與A的原型相等,兩者的原型的constuctor又都指向A本身。

需要註意的是constrctor是可以被修改的:參照MDN官方實例:constructor

function Type() { };

var	types = [
	new Array,
    [],
	new Boolean,
    true,        // remains unchanged
	new Date,
	new Error,
	new Function,
	function(){},
	Math,
	new Number,
	1,           // remains unchanged
	new Object,
	{},
	new RegExp,
	/(?:)/,
	new String,
	"test"       // remains unchanged
];

for(var i = 0; i < types.length; i++) {
	types[i].constructor = Type;
	types[i] = [ types[i].constructor, types[i] instanceof Type, types[i].toString() ];
};

console.log( types.join("\n") );

隻有,true、1、“test”這種隻讀的原生結構不可被修改constuctor

四、繼承

es6繼承

    class Father{
        constructor(name){
            this.name = name
        }
    }
    class Son extends Father{
        constructor(name,sname){
            super(name)
            this.sname = sname
        }
        getSon(){
            return this
        }
    }
    var newSon = new Son("f","s")
    console.log(newSon.getSon())  // Son {name: 'f', sname: 's'}

es5繼承的實現

    // 寄生組合繼承
    function Sub(name){
        // 優先執行this綁定,以免覆蓋子類的構造的值
        // 這裡還有一個作用是拷貝瞭父類屬性,避免所有子類共享引用屬性!!!!
        Person.call(this)
        this.name = name || 's'
    }
    // 復制一份父類的原型,避免修改原型影響其他實例
    var fn = function(){}
    fn.prototype = Person.prototype
    Sub.prototype = new fn()
    var sub = new Sub('sub')
    sub.showName() 
    // user extend.html:19
    // my name is sub extend.html:21

關於繼承詳細的可以參考這篇:前端必知必會ES5、ES6的7種繼承

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!  

推薦閱讀: