前言
Class為es6之后推薦的為了更加體現(xiàn)面向?qū)ο笏枷氲囊环N方式,但從本質(zhì)上來說它還是原型鏈的關(guān)系,也就是語法糖。而function構(gòu)造函數(shù)的方法則是es6之前常規(guī)的面向?qū)ο笏枷塍w現(xiàn)的一種方式。
本篇文章涉及的原理較多,可以結(jié)合下列文章:
面向?qū)ο笏枷?/a>、構(gòu)造函數(shù)和原型及兩者作用、原型鏈以及方法執(zhí)行順序
class本質(zhì)
在理解class本質(zhì)之前,我們先根據(jù)構(gòu)造函數(shù)的特性:
- 構(gòu)造函數(shù)具有原型對(duì)象prototype
- 構(gòu)造函數(shù)中的原型對(duì)象prototype里有constructor指向構(gòu)造函數(shù)本身
- 構(gòu)造函數(shù)可以通過原型對(duì)象添加方法
- 構(gòu)造函數(shù)創(chuàng)建的實(shí)例對(duì)象有__ proto __原型指向構(gòu)造函數(shù)的原型對(duì)象
那么,我們利用class Person{}創(chuàng)建出來的類,是否存在這些特征?
由下圖可知,類同樣有原型對(duì)象prototype且prototype中的constructor同樣指向Person類,即證明了1和2兩個(gè)論點(diǎn)

同樣的我們繼續(xù)論證,添加方法
Person.prototype.sing=function(){
console.log("唱歌");
}
let person=new Person("cc",20);
由下圖,實(shí)例對(duì)象中存在__ proto __屬性指向構(gòu)造函數(shù)的原型對(duì)象且添加了sing方法
因此class類與構(gòu)造函數(shù)之間原理是相同的,class是為了更直觀體現(xiàn)出面向?qū)ο蟆?/p>
對(duì)象設(shè)計(jì)
class
class Person {
constructor(uname, age) {
this.uname = uname;
this.age = age;
}
sing(){
console.log("唱歌");
}
}
let person=new Person("ck",20);
function
function Person(uname, age){
this.uname = uname;
this.age = age;
}
Person.prototype.sing= function(){
console.log("唱歌");
}
let person=new Person("ck",20);
靜態(tài)方法
PS:Class 內(nèi)部只有靜態(tài)方法,沒有靜態(tài)屬性。如果必須定義則類似于函數(shù)定義靜態(tài)成員變量的方式:
Person.sex="男"
之后通過調(diào)用靜態(tài)成員的方式調(diào)用即可。
類的靜態(tài)方法:在類中添加static,例如:
static dance(){
console.log("跳舞");
}
重點(diǎn):
- 如果靜態(tài)方法包含this關(guān)鍵字,這個(gè)this指的是類,而不是實(shí)例。
- 父類的靜態(tài)方法,可以被子類繼承或子類中用
super調(diào)用。
繼承
類的繼承實(shí)現(xiàn)有extends關(guān)鍵字
class Son extends Person{
constructor(uname, age) {
super(uname,age)
}
}
此時(shí)的super方法必須在constructor內(nèi)部的第一行,即子類的constructor方法沒有調(diào)用super之前,就使用this關(guān)鍵字,結(jié)果報(bào)錯(cuò),而放在super方法之后就是正確的。
構(gòu)造函數(shù)的實(shí)現(xiàn)繼承
function Son(uname,age){
Person.call(this,uname,age)
}
Son.prototype=new Person();
let son=new Son("ck",20)
注意構(gòu)造函數(shù)的繼承方法則是利用call、apply改變指針,同時(shí)子對(duì)象Son的原型對(duì)象prototype指向Person的實(shí)例對(duì)象,于是便與Person的原型鏈連接起來但卻獨(dú)立擁有自己的屬性和方法。