咱們先復(fù)習(xí)一下,什么是函數(shù)聲明,什么是函數(shù)表達(dá)式。
函數(shù)聲明:
function fun(){...}
函數(shù)表達(dá)式:
let fun = function(){...}
實(shí)際上class也是一種聲明函數(shù)的方法。
個人解釋:在es5中,通常定義一個對象,需要例如this.name=name; this.prototype.fun=function(){} 這種乏味的寫法,現(xiàn)在通過class,你就省去了prototype這一步,因?yàn)樵赾lass內(nèi)他其實(shí)都是定義在prototype上的。另外,對象屬性,統(tǒng)一寫在constructor函數(shù)中,繼承通過extends關(guān)鍵字,在繼承對象內(nèi),需要運(yùn)行一次super函數(shù)。可以通過set和get關(guān)鍵字來監(jiān)聽賦值和讀取操作,但是理論上get沒有什么用。
先初步了解一下,寫個簡單的例子,constructor方法是class內(nèi)默認(rèn)存在的函數(shù)
就算你不定義,一樣會默認(rèn)創(chuàng)建。
class內(nèi)的所有方法都是生成在prototype上的。
class man{
//默認(rèn)函數(shù) 在對象創(chuàng)建時自動調(diào)用
constructor() {
console.log("123");
}
}
let b = new man();
console.log(b);
稍微復(fù)雜一點(diǎn),把姓名和年齡加進(jìn)來,再增加一個方法。完事兒。
class man{
//默認(rèn)函數(shù) 在對象創(chuàng)建時自動調(diào)用
constructor(name,age) {
console.log("成功創(chuàng)建對象!");
this.name=name;
this.age=age;
}
getname(){
return "hello:"+this.name;
}
}
let b = new man("yunlong","30");
console.log(b.getname());
五年前,我們一直再模擬這個,用了es5中各種費(fèi)事的方法, 有用嗎,屁大點(diǎn)的事兒
搞得那么復(fù)雜,現(xiàn)在,我們可以把更多精力放在用戶體驗(yàn)上,而不是如何讓js更像編程語言。
然后我們來介紹一下,class中自帶的幾個關(guān)鍵字
1.static 關(guān)鍵字 表示:私有方法
使用了該關(guān)鍵字表示該方法不能被繼承,只能調(diào)用類本身的時候才能使用
另外,如果在其中使用了this,這里的this指function而不是實(shí)例。
class man{
//默認(rèn)函數(shù) 在對象創(chuàng)建時自動調(diào)用
constructor(name,age) {
console.log("成功創(chuàng)建對象!");
this.name=name;
this.age=age;
}
getname(){
return "hello:"+this.name;
}
static getage(){
return "年齡是:"+this.age;
}
}
let b = new man("yunlong","30");
// hello:yunlong
console.log(b.getname());
// b.getage is not a function
console.log(b.getage());
// 年齡是:undefined
console.log(man.getage());
2.extends 關(guān)鍵字 表示:繼承
官方解釋:
ES6 要求,子類的構(gòu)造函數(shù)必須執(zhí)行一次super函數(shù)。super雖然代表了父類A的構(gòu)造函數(shù),但是返回的是子類B的實(shí)例,即super內(nèi)部的this指的是B,因此super()在這里相當(dāng)于A.prototype.constructor.call(this)。
class man{
//默認(rèn)函數(shù) 在對象創(chuàng)建時自動調(diào)用
constructor(name,age) {
console.log("成功創(chuàng)建對象!");
this.name=name;
this.age=age;
}
getname(){
return "hello:"+this.name;
}
static getage(){
return "年齡是:"+this.age;
}
}
class man2 extends man{
constructor() {
// es6 要求必須執(zhí)行一次super()方法
super();
}
}
// 注意你此時 不能直接調(diào)用man2.getname()這個
let supperMan = new man2();
console.log(supperMan.getname());
看到這里,你應(yīng)該會發(fā)現(xiàn),static的方法,繼承的class是獲取不到的,如果你這個時候
想要獲取到父級的static對象,你需要把super當(dāng)一個對象來使用,
其在class中,既有super方法,也有super對象,super對象就指父級。
class man{
//默認(rèn)函數(shù) 在對象創(chuàng)建時自動調(diào)用
constructor(name,age) {
console.log("成功創(chuàng)建對象!");
this.name=name;
this.age=age;
}
getname(){
return "hello:"+this.name;
}
static getage(){
return "年齡是:"+this.age;
}
}
class man2 extends man{
constructor() {
// es6 要求必須執(zhí)行一次super()方法
super();
}
myfun(){
super.getage()
}
}
let supperMan = new man2();
console.log(man2.getage());
2.set get關(guān)鍵字 表示:監(jiān)聽賦值 讀取操作
個人解釋:
我們可以通過一個set,get關(guān)鍵字設(shè)置兩個方法,來監(jiān)聽賦值,讀取操作;例如說,你原來是obj.xx=123,現(xiàn)在你只需要
寫成obj.(監(jiān)聽的函數(shù)名不帶括號)=123,你這個123就可以被監(jiān)聽到,我們就可以通過這個來執(zhí)行一些操作,例如說,過濾對方輸入等。
class shu{
constructor(zhi) {
this.zhi=zhi;
}
get duqu(){
// 大多數(shù)情況 只需要set
return this.x;
}
set shezhi(val){
// 設(shè)置值的時候 我們主要是用這個
if(typeof val=="string"){
console.log("設(shè)置的值不是數(shù)字");
this.zhi="無法讀取";
}else{
this.zhi=val;
}
}
}
let myshu=new shu(1);
//注意此時的賦值是賦給shezhi方法的,相當(dāng)于走了一個代理。
myshu.shezhi=800;
console.log(myshu.zhi);
一般來說,用set就足夠了,使用get也非常簡單(打印對象會發(fā)現(xiàn)相當(dāng)于他多了一個duqu的變量):

class shu{
constructor(zhi) {
this.zhi=zhi;
}
get duqu(){
// 大多數(shù)情況 只需要set
if(this.zhi>300){
return "大于300";
}else{
return this.zhi;
}
}
set shezhi(val){
// 設(shè)置值的時候 我們主要是用這個
if(typeof val=="string"){
console.log("設(shè)置的值不是數(shù)字");
this.zhi="無法讀取";
}else{
this.zhi=val;
}
}
}
let myshu=new shu(1);
myshu.shezhi=800;
// 打印這個duqu
console.log(myshu.duqu);
延申!能不能在es6中使用public呢?既然都有了static?
答案是很遺憾,不能!


類本身的方法就是共有的,無需public。但是static的方法,不能被new出來的對象使用。也不能被繼承。