JavaScript类和对象

1、面向对象与面向过程

1.1 面向过程编辑POP(Process-oriented programming)

面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用就可以了。面向过程,就是按照我们分析好的步骤,按照步骤解决问题。

1.2 面向对象编程OOP(Object Oriented Programming)

面向对象是把事务分解成一个个对象,然后由对象之间分工与合作。是以对象功能来划分问题,而不是步骤。
面向对象编辑具有灵活、代码可复用、容易维护和开发的优点。
面向对象的三大特征:封装性、继承性、多态性
优点:易维护、易复用,易扩展,可以设计 出低耦合的系统,使系统更灵活、更加易于维护。
缺点:性能比面向过程低。

2、类和对象

2.1 对象

万物皆对象,对象是一个具体的事物,看得见摸得着的实物。例如:一本书、一个人可以是对象,一个数据库、一个远程服务器的连接也可以是对象。
在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,使用数据、数组、函数等。
对象是由属性和方法组件的:
● 属性:事物的特征,在对象中用属性来表示(常用名词)
● 方法:事物的行为,在对象中用方法来表示(常用动词)

2.2 类 class

在ES6中增加了类的概念,可以使用class关键字声明一个类,之后以这个类来实例化对象。
抽象了对的公共部分,它泛指某一大类(class)
对象特指某一个,通过类实例化一个具体的对象

2.3 创建类

class name{
// class body
}
创建实例:类必须使用new 实例化对象
const obj=new name()

2.4 构造函数 constructor

constructor()方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过new命令生成对象实例时,自动调用该方法。如果没有显示定义,类内部会自动给我们创建一个constructor().

1 通过class关键字创建类,首字母大写
2 constructor函数,可以接受传递过来的参数,同时返回实例对象
3 constructor只要new 生成实例时,就会自动调用这个函数,如果不写,类也会自动生成这个函数
4 生成实例,new 不能省略
5 创建类,类名后不加小括号,生成实例 类名后面要加小括号,构建函数不需要function

3、类的继承

3.1 super关键字

super 用于访问和 调用对象父类上的函数。可以调用父类的构造函数,也可以调用父类的普通函数。

   class Person {
    
    
        // 构造函数,
        constructor(name, age) {
    
    
          this.name = name;
          this.age = age;
        }
        // 普通函数
        funStr() {
    
    
          console.log(`姓名:${
      
      this.name},年龄:${
      
      this.age}`);
        }
      }
      class Son extends Person {
    
    
        constructor(name, age) {
    
    
          super(name, age);
        }
      }
      var son = new Son('刘天王', 22);
      son.funStr();

在这里插入图片描述

  1. 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
  2. 继承中,如果子类里没有,就去找父类有没有这个方法,就执行父类的这个方法
  3. 可以通过super直接调用父类的方法
class Person {
    
    
        // 构造函数,
        constructor(name, age) {
    
    
          this.name = name;
          this.age = age;
        }
        // 普通函数
        funStr() {
    
    
          console.log(`父类的方法`);
        }
      }
      class Son extends Person {
    
    
        constructor(name, age) {
    
    
          super(name, age); // 调用父类的构造函数
        }
        funStr() {
    
    
          console.log(`子类的方法`);
          super.funStr(); // 通过super直接调用父类的方法
        }
      }
      var son = new Son('刘天王', 22);
      son.funStr();

3.2 类的继承extends

子类在构造函数中使用super,必须放到this前面(必须先调用父类的构造方法)

class Person {
    
    
  constructor(name, age) {
    
    
    this.name = name;
  }
}
class Student extends Person {
    
    
  // 子类继承父类
  constructor(name, other) {
    
    
    super(name); // 调用父类的constructor
    this.other = other; // 定义子类的属性
  }
}
// 父类
class Animal {
    
    
  constructor(name) {
    
    
    this.name = name;
  }
  sayHello() {
    
    
    console.log('动物在叫~');
  }
}

/**
 * 使用继承后,子类会拥有父类所有的方法和属性
 * 如果子类中添加了和父类相同的方法,则子类方法会覆盖父类的方法(方法重写)
 */
class Dog extends Animal {
    
    
  constructor(name, age) {
    
    
    // 如果子类中写了构造函数,在子类构造函数中必须对父类构造函数调用
    super(name); // 调用父类的构造函数
    this.age = age;
  }
  sayHello() {
    
    
    console.log('Dog:汪汪汪');
  }
  // 子类扩展方法
  run() {
    
    
    console.log(`${
      
      this.name}在跑……`);
  }
}
class Cat {
    
    
  constructor(name, age) {
    
    
    super(name);
    this.age = age;
  }
  sayHello() {
    
    
    console.log('喵喵喵喵');
  }
}

const dog = new Dog('旺财', 3);
dog.sayHello();

3.3 ES6中的类和对象

1.在ES6中类没有变量提升,所以必须先定义类,才能通过类实例化对象
2.类里面的共有属性和方法一定要加this使用
3.类里面的this指向问题
4.consturctor里面的this指向实例对象,方法里的this指向这个方法的调用者

4、构造函数和原型

4.1 构造函数

构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里。
new在执行时会做四件事性:

  1. 在内存中创建一个新的空对象
  2. 让this指向这个新的对象
  3. 执行构造函数里的代码,给这个新对象添加属性和方法
  4. 返回这个新对象(所以构造函数里面不需要return)
        // 1. 利用 new Object() 创建对象
        var obj1 = new Object();
        // 2. 利用 对象字面量创建对象
        var obj2 = {
    
    };
        // 3. 利用构造函数创建对象
        function Star(uname, age) {
    
    
            this.uname = uname;
            this.age = age;
            this.sing = function() {
    
    
                console.log('我会唱歌');

            }
        }
        var ldh = new Star('刘德华', 18);
        var zxy = new Star('张学友', 19);
        console.log(ldh);
        ldh.sing();
        zxy.sing();

4.2 实例成员和静态成员

构造函数中的属性和方法称为成员

  1. 实例成员:构造函数内部通过this添加的成员 name,fun 就是实例成员,实例成员只能通过实例化对象来访问
  2. 静态成员:在构造函数本身上添加的成员 ,静态成员只能通过构造函数访问
function Star(name){
    
    
this.name = name;
this.fun = function(){
    
    
  console.log('我是函数') 
}
}

var obj = new Star('刘德华');
console.log(obj.name); // 访问实例成员

Star.age=18;
console.log(Star.age); // 静态成员只能通过构造函数访问

4.3 构造函数原型 prototype

构造函数通过原型分配的函数是所有对象所**共享**的。
每个构造函数都有一个prototype属性,指向另一个对象,注意这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。

4.4 对象原型 proto

对象都会有一个属性 __proto__指向构造函数的prototype 原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在。

  • __proto__对象原型和原型对象的prototype是等价的
  • __proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象prototype
    在这里插入图片描述

对象原型(__proto__)构造函数(prototype)原型对象 里面都有一个属性 constructor属性,constructor我们称为构造函数,因为它指回构造函数本般。
constructor主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。
构造函数、实例、原型对象三者之间的关系
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/lqh4188/article/details/128624780