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>