摘要:在上一篇文章里我介紹了一下面向對象編程的概念,在最后終于喜出望外看到了提供了類的概念了。而到了里面真正的類與構造函數現在是分離的,通過上面的代碼可以看出來,這種寫法正是面向對象的正統寫法。
在上一篇文章里我介紹了一下面向對象編程的概念,在最后終于喜出望外看到了ES6提供了類的概念了。那這個類如何去用,是這篇文章的主題。ES6給我們提供了一個class關鍵字。這個關鍵字跟以前的var let const很像,它們都是用做聲明的,而class就是用來聲明一個類的。
語法class name [extends]{ //extends是用來繼承的,可選參數 //class body };
注意
class不能重復聲明(與let、const一樣)
類的本質還是一個構造函數
class Div{ //類 constructor(x,y){ //構造函數 this.x=x; //共享屬性,放在constructor里 this.y=y; }//注意這里是沒有逗號的 move(){ //共享方法,這里相當于在Div.prototye上添加方法 console.log("動起來"); } } console.dir(Div); //在控制臺里看一下與ES5的面向對象程序有什么不同
在ES5里面的面向對象,所謂的“類”與構造函數其實是一個東西,也就是雙重角色。而到了ES6里面真正的類與構造函數現在是分離的,通過上面的代碼可以看出來,這種寫法正是面向對象的正統寫法。同時,我們在控制臺里看到這個對象與ES5的對象區別僅在于顯示的名字上多了一個class關鍵字,如下圖:
下面我要詳細的對比一下ES5與ES6的面向對象有什么區別,以及用這種方式寫出來的對象與ECMAScript的內置對象有什么區別,這樣做的目的能讓你清晰的明白面向對象編程究竟是一種什么樣的形式。
1、與ES5對比const [div1,div2]=[new Div(10,20),new Div(15,20)]; //這兩個對象是為了對比他們身上的原型 div1.z=30; //給實例添加一個私有屬性 console.log( typeof Div, //function 構造函數(雖說是類,但實質還是構造函數) Div.prototype.constructor===Div, //true 類本質還是構造函數(披著羊皮的狼) //Object.getPrototypeOf方法是用來取對象身上的原型,用它代替__proto__ Object.getPrototypeOf(div1)===Div.prototype, //true 實例的原型就是構造函數的原型 Object.getPrototypeOf(div1)===Object.getPrototypeOf(div2), //true 兩個實例的原型都一樣,指向構造函數的原型對象 div1 instanceof Div, //true div是它的實例 div1.constructor===Div, //true 實例的構造函數就是類 /* * 方法說明 * 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"] 所有方法都是可枚舉的
從上面的代碼得出以下的結論
2、與內置對象對比類的本質還是構造函數,其實class就是個語法糖,它的內部還是個構造函數
class聲明的對象與ES5聲明的對象實質上一樣
class聲明的對象,它身上的方法都不能被枚舉
const [d1,d2]=[new Date(),new Date()]; //聲明兩個內置對象實例 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), //內置對象身上的方法都是不可枚舉的 );
從上面的代碼得出以下的結論
添加屬性與方法自定義對象就是我們聲明的一個類似于內置對象的對象
JavaScript的面向對象編程,實質是把某個功能寫成一個對象,并且這個對象是在模仿內置對象
class聲明的對象同樣允許小伙伴們任性的添加屬性與方法,包括共享與私有的。
共享屬性放在constructor里,共享方法放在大括號內
私有屬性放在類身上,私有方法放在大括號內同時前面要加static關鍵字
私有方法里this指向類本身,其它方法里的this指向實例對象
class Bear{ constructor(){ this.name="熊大"; //共享屬性(放在constructor里) } sleep(){ //共享方法(直接放在大括號里) this.name="熊二"; //this指向實例,所以在這里給this添加屬性還是實例的屬性 console.log(`${this.name}愛睡覺`); } static gohome(){ //私有方法 //類會默認添加一個name屬性,值為class后面的那個單詞 console.log(`${this.name}的家在森林`); //這里的this并不會指向實例,而是指向類 } } //共享屬性與方法 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(); //報錯,它是私有方法
下篇文章會詳細介紹class里的繼承。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/96657.html
摘要:源碼下載至此再和面向對象談戀愛系列文章已經全部更新完畢寫文章不易,且行且珍惜 再和面向對象談戀愛 - 對象簡介(一)再和面向對象談戀愛 - 對象相關概念(二)再和面向對象談戀愛 - 面向對象編程概念(三)再和面向對象談戀愛 - class(四)再和面向對象談戀愛 - 繼承(五)再和面向對象談戀愛 - super(六) 通過前面的六篇文章已經把ES6的面向對象跟大伙說清楚了,大家最關心的...
摘要:說到底面向對象才是程序語言的根本。其實面向對象編程說的就是自定義對象。里并沒有類的概念,所以嚴格上來講這是個假的面向對象里的面向對象編程現在好了,終于聽到別人鄙視我們了,給我們提供了類這個概念,其實是向傳統語言更靠齊了。 通過前兩篇文章,我們了解了對象的概念以及面向對象里的相關概念等知識,那前面說了對象分類里的前兩種,這篇文章要詳細去說第三種自定義對象,那真正的好戲這就來了! 面向對象...
摘要:同時彈出的結果是指向了子類,又說明雖然調用的是父類的構造函數,但是調用完后會指向子類,指向也被改成了子類的實例。 在上一篇文章里介紹了繼承,那其中說過一個很關鍵的東西想要繼承子類里里必需先調用一個super方法。而super的作用絕對是價值連城!同時super的作用還有多種,并且跟你的使用環境有關系。 1、當作函數使用 super被當作函數使用,這種情況是最普遍的,上一篇文章里已經使用...
摘要:面向對象里最大的特點應該就屬繼承了。在第二篇文章里說過原型實例跟構造函數之間的繼承,并且還講了一道推算題。 通過上一篇文章想必各位老鐵已經熟悉了class了,這篇文章接著介紹繼承。面向對象里最大的特點應該就屬繼承了。一個項目可能需要不斷的迭代、完善、升級。那每一次的更新你是要重新寫呢,還是在原有的基礎上改吧改吧呢?當然,不是缺心眼的人肯定都會在原來的基礎上改吧改吧,那這個改吧改吧就需要...
摘要:所有的對象都是由構造函數創建的對象哪來的構造函數生的。而普通函數不能生成對象不孕不育,構造函數可以生成對象有生育能力。別急,記住那句話永遠指向實例對象對應的構造函數的,那就先看實例對象是誰。 上一篇文章把對象的概念講解了一下,這篇文章要重點解釋最讓大家犯迷糊的一些概念,包括 構造函數 實例 繼承 構造函數的屬性與方法(私有屬性與方法) 實例的屬性與方法(共享屬性與方法) protot...
閱讀 888·2021-09-22 15:17
閱讀 1917·2021-09-22 15:06
閱讀 2211·2021-09-08 09:35
閱讀 5099·2021-09-01 11:43
閱讀 3476·2019-08-30 15:55
閱讀 2150·2019-08-30 12:48
閱讀 3150·2019-08-30 12:45
閱讀 1782·2019-08-29 17:31