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>

