目录
一、面向过程与面向对象
1、面向过程
2、面向对象
3、面向过程优缺点
4.面向对象优缺点
二、类class
1、class创建
2、类:constructor 构造函数
3、类中添加方法
4、类的继承
5、super关键字
6、static
7、ES6注意事项:
8、类声明和类表达式的主体都执行在严格模式下。
一、面向过程与面向对象
1、面向过程
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步的实现,使用的时候再一个一个的一次调用就可以了。
2、面向对象
1)面向对象是把事务分解成为一个个对象,然后对象之间分工与合作。
2)面向对象是以功能来划分问题,而不是步骤。
3)面向对象的特性:封装性、继承性、多态性
3、面向过程优缺点
优点:性能相对较高,适合跟硬件联系很紧密的东西,比如单片机。
缺点:没有面向对象容易维护,复用,扩展等。
4.面向对象优缺点
优点:容易维护,复用,扩展,由于面向对象有封装,继承,多态的特性,可以设计出低耦合的系统,是系统更加灵活,更加易于维护
缺点:性能比面向过程低。
二、类class
类是用于创建对象的模板。
1、class创建
//1、创建类 class
class Start{
}
//2、利用类创建对象 new
new Start();
2、类:constructor 构造函数
constructor()方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过new命令生成对象实例时,自动调用该方法。如果没有显示定义,类内部会自动给我们创建一个constructor()
class Start{
//类的构造函数(默认方法)
//用于传递参数,返回实例对象,通过new命令生成对象实例时,自动调用该方法
constructor(name){
this.name=name;
}
}
//调用的时候一定要加new,一调用就会自动执行constructor构造函数
let str=new Start("小刘");
console.log(str.name);//小刘
let p=class Father{
constructor(name,age){
this.name=name;
this.age=age;
}
sing(){
console.log(111);
}
}
let obj1=new p();
console.log(p.name);//Father
// console.log(p.sing());//报错
obj1.sing();//11
总结:(1)通过class 关键字创建类,类名我们还是习惯性定义首字母大写
(2)类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象
(3) constructor函数只要new生成实例时,就会自动调用这个函数,如果我们不写这个函数,也会自动生成这个函数
(4)生成实例new不能省略
(5)最后注意语法规范,创建类时,类名后面不要加小括号,生成实例类名后面加小括号,构造函数不需要加function
(6)类表达式也可以定义类。类表达式可以命名或不命名。命名类表达式的名称是该类体的局部名称
3、类中添加方法
(1)类中的所有函数都不需要加function
(2)多个函数方法之间不需要逗号分隔,不然要报错
(3)方法还可以传递参数,类中的公有属性是放到constructor里面的,调用的时候一定要加new,一调用就会自动执行constructor构造函数
class Start{
constructor(name){
this.name=name;
}
sing(list){
console.log("...唱歌");
console.log( this.name + list);//鱼鱼----冬天
}
}
let str1=new Start("鱼鱼");
str1.sing("----冬天");
4、类的继承
(1)写法:
class Father{ //父类
}
class Son extends Father{ //子类继承父类
}
(2)用法:
class Father{ //父类
constructor(){
}
fish(){
console.log("鱼鱼鱼");
}
}
class Son extends Father{ //子类继承父类
}
//给子类实例化
let son=new Son();
son.fish();//鱼鱼鱼
5、super关键字
super关键字用于访问和调用对象父类上的函数;
可以调用父类的构造函数,也可以调用父类的普通函数(就近原则)
注意:子类在构造函数中使用super,必须放到this前面(必须先调用父类的构造方法,在使用子类构造方法)
例子1:用super调用父类中的构造函数可以实现:可以调用父类的构造函数
假如子类要向父类里面传递参数然后显示结果,那么要注意this的指向问题
class Father{
constructor(x,y){
this.x=x;
this.y=y;
}
sum(){
console.log(this.x+this.y);//this指向的是父类constructor的数据,也必须是父类的数据才能相加
}
}//这样写是错的
class Son extends Father{
constructor(x,y){
this.x=x; //这里的this指向是子类Son,所以不能将子类的实参传递给父类的形参
this.y=y;
}
}
let son1=new Son(1,2);//这里的1,2传给了子类Son的constructor
son1.sun();
解决方法:在继承里面添加一个super//super必须写在子类this之前!调用了父类里面的constroctor构造函数,将x,y传给父类,就可以输出结果了
class Son extends Father{
constructor(x,y){
super(x,y);
}
}
例子2:调用父类的普通函数
class Father{
say(){
return "zzzzzz"
}
}
class Son extends Father{
say(){
console.log("bbbbbbb");
super.say()//可以调用父类的函数
console.log(super.say());
}
}
let son3=new Son();
son3.say(); //没有调用super之前的结果:bbbbbbb super调用父类后的结果: zzzzzz
总结:继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则)
6、static
1)static只能通过类来访问。即static只能通过类自身来调用,不能通过类的实例来调用。
class Father{
constructor(name,age){
this.name=name;
this.age=age;
}
sing(){
console.log(this.name+'我今天真的好累');
}
static fb(){
console.log(this.name);
}
}
Father.song=function (){
console.log(this.name);
}
let obj1=new Father('才才',18);
obj1.sing();
//obj1.song();//报错
// obj1.fb();//报错
Father.fb();//Father
Father.song();//Father
2)静态方法调用同一个类中的其他静态方法,可使用 this 关键字。
3)非静态方法中,不能直接使用 this 关键字来访问静态方法。而是要用类名来调用;或者用构造函数的属性来调用该方法。
7、ES6注意事项:
(1)在ES6中类没有变量提升,所以必须先定义类,才能通过类实例化对象;
(2)类里面的共有的属性和方法一定要加this使用
(3)类里面this的指向问题
(4)constructor里面的this指向实例对象方法里面的this指向这个方法的调用者
示例:做一个点击完毕后调用sing的方法
<button>按钮</button>
<script>
//类里面的共有的属性和方法一定要加this使用
class Star{
constructor(name,age){
//constructor里面的this指向实例化对象
//console.log(this);//s1实例对象
this.name=name;
this.age=age;
//可以直接在constructor里面调用sing方法,因为加了new就会马上调用constructor构造函数
// this.sing();//小徐(实例对象调用的sing)
//点击调用sing方法:首先先获取按钮(按钮是属于si实例对象的)
this.btn=document.querySelector("button");
this.btn.onclick=this.sing;
}
sing(){
//方法里面的this指向调用它的那个调用者
//点击事件后调用sing,所以这里的this指向btn按钮
console.log(123);
//console.log(this.name);
}
}
let s1=new Star("小徐",18);
//s1.sing();//123 小徐
8、类声明和类表达式的主体都执行在严格模式下。
1)严格模式会将JavaScript陷阱直接变成明显的错误。
2)严格模式修正了一些引擎难以优化的错误。
3)同样的代码有些时候严格模式会比非严格模式下更快。
4)严格模式禁用了一些有可能在未来版本中定义的语法。
使用 ‘use strict’; 进入严格模式
类必须使用new实例化对象