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>

