目录

一、面向过程与面向对象

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实例化对象