1、面向對象
(1)特點
抽取對象共有的屬性和行為封裝為一個類
對類進行實例化獲取類中的對象
(2)對象
一個具體的事物,用屬性和方法來描述一個對象
(3)類
用class關鍵字聲明一個類,類抽象出了對象的公共部分,它泛指某一大類
2、類
(1)類的創建
<body> <div class="box"></div> <script> class student{ constructor(username){ this.username=username; } } var stu=new student("zhai"); console.log(stu.username); </script> </body>
constructor是構造函數,new生成實例的時候用於初始化對象
(2)類的方法
不帶參數:
<body> <div class="box"></div> <script> class student{ constructor(username){ this.username=username; } study(){ console.log("我愛學習") } } var stu=new student("zhai"); console.log(stu.username); stu.study(); </script> </body>
帶參數的方法:
<body> <div class="box"></div> <script> class student { constructor(username) { this.username = username; } study(sub) { console.log(this.username + "愛學習" + sub) } } var stu = new student("zhai"); console.log(stu.username); stu.study("Java"); </script> </body>
方法不需要加function關鍵字
方法之間不需要加關鍵字進行分割
3、類的繼承
子類繼承父類的屬性和方法,class Son extends Father(),和java的語法極為相似,這里不再舉例
子類不能繼承父類的構造方法,需要使用super關鍵字來調用父類的構造函數,super必須寫在第一行
存在方法的重寫,super關鍵字也可以在子類中調用父類的普通函數
4、類與對象
先創建類才能實例化
二、構造函數和原型
ES6之前對象不是基於類創建的,而是用一種稱之為構造函數的特殊函數來定義對象和他們的特征
1、構造函數創建對象
<body> <div class="box"></div> <script> function Student(username,age){ this.username=username; this.age=age; this.sing=function(){ console.log("我愛唱歌"); } } var stu=new Student("zhai","abcd"); stu.sing(); console.log(stu); </script> </body>
2、實例成員與靜態成員
username、age、sing這樣的通過this關鍵字添加的成員稱為實例成員,實例成員只能通過實例化的對象來訪問
在構造函數本身上添加的成員稱為靜態成員,靜態成員只能通過構造函數來訪問
<body> <div class="box"></div> <script> function Student(username,age){ this.username=username; this.age=age; this.sing=function(){ console.log("我愛唱歌"); } } var stu=new Student("zhai","abcd"); stu.sing(); console.log(stu); Student.phone="123123123"; console.log(Student.phone); </script> </body>
3、原型對象
(1)構造函數方式的缺陷
構造函數雖然好用,但是存在內存浪費的問題,因為不同的對象是放在不同的地址中的
<body> <div class="box"></div> <script> function Student(username,age){ this.username=username; this.age=age; this.sing=function(){ console.log("我愛唱歌"); } } var stu=new Student("zhai","abcd"); var stu1=new Student("zhang","aaa"); console.log(stu==stu1); </script> </body>
在上面的構造函數中有一個方法,每一個對象都會有該方法,顯然是浪費內存的
(2)構造函數的原型對象
<body> <div class="box"></div> <script> function Student(username,age){ this.username=username; this.age=age; } Student.prototype.sing=function(){ console.log("我愛唱歌"); } var stu=new Student("zhai","abcd"); var stu1=new Student("zhang","aaa"); console.log(stu.sing()); console.log(stu1.sing()); </script> </body>
聲明了原型對象后多個對象可以共享同一個方法,能夠節約資源,下面的例子打印結果為true:
<body> <div class="box"></div> <script> function Student(username,age){ this.username=username; this.age=age; } Student.prototype.sing=function(){ console.log("我愛唱歌"); } var stu=new Student("zhai","abcd"); var stu1=new Student("zhang","aaa"); console.log(stu.sing()==stu1.sing()); </script> </body>
一般情況下,我們的公共屬性定義到構造函數里面,公共的方法我們放到原型對象身上
在對象身上系統添加的有一個_proto_指向我們構造函數的原型對象,如:下面的例子返回true
<body> <div class="box"></div> <script> function Student(username,age){ this.username=username; this.age=age; } Student.prototype.sing=function(){ console.log("我愛唱歌"); } var stu=new Student("zhai","abcd"); var stu1=new Student("zhang","aaa"); console.log(stu.__proto__===stu1.__proto__); </script> </body>
4、constructor構造函數
對象原型和構造函數的原型對象里面都有一個constructor屬性,我們稱之為構造函數,因為它返回構造函數本身
<body> <div class="box"></div> <script> function Student(username,age){ this.username=username; this.age=age; } Student.prototype.sing=function(){ console.log("我愛唱歌"); } var stu=new Student("zhai","abcd"); var stu1=new Student("zhang","aaa"); console.log(Student.prototype); console.log(stu.__proto__); </script> </body>