十六、Class类

郁子大约 3 分钟约 905 字笔记ECMAScript尚硅谷李强

(一)简介

  • ES6 引入 Class 类的概念,作为对象的模板
  • 通过 class 关键字可以定义类
  • 可以看做一个语法糖,绝大部分功能 ES5 都可以实现
  • 新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法

1.ES5

// 手机类
function Shouji(brand, price) {
  this.brand = brand;
  this.price = price;
}

// 添加方法
Shouji.prototype.call = function () {
  console.log("我可以打电话");
};

// 实例化对象
let Huawei = new Shouji("华为", 5999);
console.log(Huawei);
Huawei.call();
// Shouji {brand: '华为', price: 5999}
// 我可以打电话

2.ES6

class Phone {
  // 构造方法:特殊的方法,名字固定,new类对象时自动执行
  constructor(brand, price) {
    this.brand = brand;
    this.price = price;
  }

  // 方法必须使用该语法,不能使用ES5的对象完整形式【call: function() {}】
  call() {
    console.log("我可以打电话!!!");
  }
}

let XiaoMi = new Phone("小米", 1999);
console.log(XiaoMi);
XiaoMi.call();
// Phone {brand: '小米', price: 1999}
// 我可以打电话!!!

(二)Class 静态成员

  • 实例对象的属性和方法和函数对象是不相通的
  • 实例对象的属性和方法和构造函数的原型对象相通
  • namechange 属于函数对象,不属于实例对象
    • 这样的属性称作静态成员
    • 即:在面向对象编程中,namechange 属于类而不属于实例对象
  • https://www.cnblogs.com/rickdiculous/p/13670315.htmlopen in new window
// 以下是函数对象
function Shouji() {}
Shouji.name = "手机";
Shouji.change = function () {
  console.log("我可以改变世界");
};
Shouji.prototype.size = "5.5inch";

// 以下是实例对象
let nokia = new Shouji();
console.log(nokia.size);
// 5.5inch

console.log(nokia.name);
// undefined
nokia.change();
// nokia.change is not a function

// 以上类似于面向对象中
class Phone {
  // 静态属性
  static name = "手机";
  static change() {
    console.log("我可以改变世界");
  }
}
let xiaomi = new Phone();
console.log(xiaomi.name);
console.log(Phone.name);

(三)ES5 构造函数继承

// 手机
function Phone(brand, price) {
  this.brand = brand;
  this.price = price;
}
Phone.prototype.call = function () {
  console.log("我可以打电话");
};

// 智能手机
function SmartPhone(brand, price, color, size) {
  Phone.call(this, brand, price);
  this.color = color;
  this.size = size;
}

// 设置子级构造函数的原型
SmartPhone.prototype = new Phone();
// 做一个校正,可不加
SmartPhone.prototype.constructor = SmartPhone;

// 声明子类的方法
SmartPhone.prototype.photo = function () {
  console.log("我可以拍照");
};
SmartPhone.prototype.playGame = function () {
  console.log("我可以玩游戏");
};

// 实例化
const chuizi = new SmartPhone("锤子", 2499, "黑色", "5.5inch");
console.log(chuizi);
// SmartPhone {brand: '锤子', price: 2499, color: '黑色', size: '5.5inch'}

(四)Class 类继承

1.使用 super 调用父类构造方法

class Phone {
  // 构造方法
  constructor(brand, price) {
    this.brand = brand;
    this.price = price;
  }

  // 父类的成员属性
  call() {
    console.log("我可以打电话!!!");
  }
}

class SmartPhone extends Phone {
  // 构造方法
  constructor(brand, price, color, size) {
    // ES5:Phone.call(this, brand, price);
    super(brand, price);
    this.color = color;
    this.size = size;
  }

  photo() {
    console.log("拍照");
  }
  playGame() {
    console.log("玩游戏");
  }
}

const xiaomi = new SmartPhone("小米", 799, "黑色", "4.7inch");
console.log(xiaomi);
// SmartPhone {brand: '小米', price: 799, color: '黑色', size: '4.7inch'}
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();
// 我可以打电话!!!
// 拍照
// 玩游戏

2.重写父类方法

  • 因为子类不能直接调用父类同名方法,所以只能完全重写
class Phone {
  // 构造方法
  constructor(brand, price) {
    this.brand = brand;
    this.price = price;
  }

  // 父类的成员属性
  call() {
    console.log("我可以打电话!!!");
  }
}

class SmartPhone extends Phone {
  // 构造方法
  constructor(brand, price, color, size) {
    // ES5:Phone.call(this, brand, price);
    super(brand, price);
    this.color = color;
    this.size = size;
  }

  photo() {
    console.log("拍照");
  }
  playGame() {
    console.log("玩游戏");
  }

  // 重写父类方法
  call() {
    console.log("我可以视频通话!!!");
  }
}

const xiaomi = new SmartPhone("小米", 799, "黑色", "4.7inch");
xiaomi.call();
// 我可以视频通话!!!

(五)Class 中的 getters 和 setters

class Phone {
  // 构造函数可以缺省

  get price() {
    console.log("价格属性被读取了。");
    return 123;
  }

  set price(value) {
    console.log("价格属性被修改了。");
  }
}

// 实例化对象
let s = new Phone();
console.log(s.price);
// 价格属性被读取了。
// 123

s.price = "free";
// 价格属性被修改了。
上次编辑于: