溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

再和“面向?qū)ο蟆闭剳賽?- class(四)

發(fā)布時間:2020-04-10 18:08:32 來源:網(wǎng)絡(luò) 閱讀:659 作者:陳學(xué)輝 欄目:web開發(fā)

在上一篇文章里我介紹了一下面向?qū)ο缶幊痰母拍?,在最后終于喜出望外看到了ES6提供了類的概念了。那這個類如何去用,是這篇文章的主題。ES6給我們提供了一個class關(guān)鍵字。這個關(guān)鍵字跟以前的var let const很像,它們都是用做聲明的,而class就是用來聲明一個類的。

語法

class name [extends]{   //extends是用來繼承的,可選參數(shù)
    //class body
};

注意

  • class不能重復(fù)聲明(與let、const一樣)
  • 類的本質(zhì)還是一個構(gòu)造函數(shù)
class Div{  //類
    constructor(x,y){   //構(gòu)造函數(shù)
        this.x=x;   //共享屬性,放在constructor里
        this.y=y;
    }//注意這里是沒有逗號的
    move(){ //共享方法,這里相當(dāng)于在Div.prototye上添加方法
        console.log('動起來');
    }
}
console.dir(Div);   //在控制臺里看一下與ES5的面向?qū)ο蟪绦蛴惺裁床煌?/code>

ES5里面的面向?qū)ο螅^的“類”與構(gòu)造函數(shù)其實是一個東西,也就是雙重角色。而到了ES6里面真正的類與構(gòu)造函數(shù)現(xiàn)在是分離的,通過上面的代碼可以看出來,這種寫法正是面向?qū)ο蟮恼y(tǒng)寫法。同時,我們在控制臺里看到這個對象與ES5的對象區(qū)別僅在于顯示的名字上多了一個class關(guān)鍵字,如下圖:
再和“面向?qū)ο蟆闭剳賽?- class(四)

下面我要詳細(xì)的對比一下ES5ES6的面向?qū)ο笥惺裁磪^(qū)別,以及用這種方式寫出來的對象與ECMAScript的內(nèi)置對象有什么區(qū)別,這樣做的目的能讓你清晰的明白面向?qū)ο缶幊叹烤故且环N什么樣的形式。

1、與ES5對比

const [div1,div2]=[new Div(10,20),new Div(15,20)];  //這兩個對象是為了對比他們身上的原型
div1.z=30;  //給實例添加一個私有屬性

console.log(
    typeof Div, //function 構(gòu)造函數(shù)(雖說是類,但實質(zhì)還是構(gòu)造函數(shù))
    Div.prototype.constructor===Div,    //true 類本質(zhì)還是構(gòu)造函數(shù)(披著羊皮的狼)

    //Object.getPrototypeOf方法是用來取對象身上的原型,用它代替__proto__
    Object.getPrototypeOf(div1)===Div.prototype,    //true 實例的原型就是構(gòu)造函數(shù)的原型
    Object.getPrototypeOf(div1)===Object.getPrototypeOf(div2),  //true 兩個實例的原型都一樣,指向構(gòu)造函數(shù)的原型對象

    div1 instanceof Div,        //true div是它的實例
    div1.constructor===Div,     //true 實例的構(gòu)造函數(shù)就是類

    /*
     * 方法說明
     *  Object.getOwnPropertyNames()這個方法是用來獲取對象身上的所有屬性名
     *  hasOwnProperty()用來判斷某個屬性是對象自身的(true),還是繼承自原型對象的(false)
     *  Object.keys()返回對象所有可枚舉(遍歷)的屬性名
     */
    Object.getOwnPropertyNames(div1),//["x", "y", "z"] 實例自己的屬性
    div1.hasOwnProperty('x'),       //true 實例的屬性
    div1.hasOwnProperty('move'),    //false 這個方法是繼承而來的
    Object.keys(Div.prototype)      //[] 對象身上的方法都是不可枚舉的
);

//ES5定義的對象,身上的方法是可以枚舉的
function Car(){}
Car.prototype.drive=function(){
    console.log('竄的老快了');
}
console.log(Object.keys(Car.prototype));  //["drive"] 所有方法都是可枚舉的

從上面的代碼得出以下的結(jié)論

  1. 類的本質(zhì)還是構(gòu)造函數(shù),其實class就是個語法糖,它的內(nèi)部還是個構(gòu)造函數(shù)
  2. class聲明的對象與ES5聲明的對象實質(zhì)上一樣
  3. class聲明的對象,它身上的方法都不能被枚舉

2、與內(nèi)置對象對比

const [d1,d2]=[new Date(),new Date()];  //聲明兩個內(nèi)置對象實例
d1.x=10,d1.y=20,d1.z=30;    //給實例添加三個私有屬性

console.log(
    typeof Date,    //function
    Date.prototype.constructor===Date,  //true
    Object.getPrototypeOf(d1)===Date.prototype, //true
    Object.getPrototypeOf(d1)===Object.getPrototypeOf(d1),  //true
    d1 instanceof Date, //true
    d1.constructor===Date,  //true
    Object.getOwnPropertyNames(d1), //["x", "y", "z"]
    d1.hasOwnProperty('x'),  //true
    d1.hasOwnProperty('getDate'),   //false 這個方法是繼承于Date對象的
    Object.keys(Date.prototype),    //內(nèi)置對象身上的方法都是不可枚舉的
);

從上面的代碼得出以下的結(jié)論

  1. 自定義對象就是我們聲明的一個類似于內(nèi)置對象的對象
  2. JavaScript的面向?qū)ο缶幊?,實質(zhì)是把某個功能寫成一個對象,并且這個對象是在模仿內(nèi)置對象

添加屬性與方法

class聲明的對象同樣允許小伙伴們?nèi)涡缘奶砑訉傩耘c方法,包括共享與私有的。

  • 共享屬性放在constructor里,共享方法放在大括號內(nèi)
  • 私有屬性放在類身上,私有方法放在大括號內(nèi)同時前面要加static關(guān)鍵字
  • 私有方法里this指向類本身,其它方法里的this指向?qū)嵗龑ο?/li>
class Bear{
    constructor(){
        this.name='熊大';   //共享屬性(放在constructor里)
    }
    sleep(){    //共享方法(直接放在大括號里)
        this.name='熊二'; //this指向?qū)嵗?,所以在這里給this添加屬性還是實例的屬性
        console.log(`${this.name}愛睡覺`);
    }
    static gohome(){    //私有方法
        //類會默認(rèn)添加一個name屬性,值為class后面的那個單詞
        console.log(`${this.name}的家在森林`);  //這里的this并不會指向?qū)嵗侵赶蝾?    }
}

//共享屬性與方法
const b1=new Bear();
console.log(b1.name);   //熊大    
b1.sleep(); //熊大愛睡覺
console.log(b1.name);   //熊二  sleep里重新定義了name屬性,所以在這就被改了

//私有屬性與方法
Bear.age=5;     //在外面添加私有屬性
console.log(b1.age);    //undefined 實例不具備
Bear.gohome();          //Bear的家在森林
//b1.goHome();          //報錯,它是私有方法

下一篇文章會詳細(xì)介紹class里的繼承。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI