【ES6】中构造函数的语法糖——Class(类)

一、引言

在现代前端开发中,JavaScript的面向对象编程成为了主流。ES6引入了class关键字,使得开发者可以更方便地使用面向对象的方式编写代码,更接近传统语言的写法。ES6的class可以看作是一个语法糖,它的绝大部分功能ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法。

二. 定义和使用class

在JavaScript中,class是创建对象的一种方式,它定义了一个类的模板,包含了属性和方法的声明,在底层中仍然是使用原型和基于原型的继承。

// ES5写法
function ShuiGuo(name, price){
  this.name = name;
  this.price = price;
}
// 添加方法
ShuiGuo.prototype.eat = function(){
  console.log("吃水果啦!");
}
// 实例化对象
let shuiguo = new ShuiGuo("杨梅", 50);
console.log(shuiguo);
shuiguo.eat();
// ES6写法
class Fruit{
  // 构造方法
  constructor(name, price){
    this.name = name;
    this.price = price;
  }
  eat(){
    console.log("吃水果啦!");
  }
}
let fruit = new Fruit("西瓜", 50);
console.log(fruit);
fruit.eat();

【ES6】中构造函数的语法糖——Class(类)

在上面的代码示例中,我们定义了一个Fruit类,它有一个constructor构造函数和一个eat方法。构造函数用于初始化对象的属性,而方法用于定义对象的行为。通过new关键字我们可以创建Fruit类的实例,并调用其方法。

  1. class 类名{},不要写成class 类名(){},不用加小括号。
  2. constructor构造函数与eat方法之间不用写逗号。
  3. 定义方法时直接写eat(){},不要写成eat:function(){},不用冒号也不用写function。

三、constructor构造函数

在类(class)中,constructor是一个特殊的方法,用于在创建对象时初始化实例属性和方法。它接受传递给类的参数,并使用它们来创建和初始化类的对象。constructor方法是类中默认的构造函数,constructor这个关键字是固定的,不能随意修改。

当一个实例化对象被创建时,它会自动调用constructor方法以初始化自己,用于实例化对象时初始化属性和方法。当使用new关键字创建类的实例时,构造函数会被自动调用。它是一个默认的方法,如果没有手动定义,则会自动在类中创建。

class Rectangle {
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }
  getArea() {
    return this.width * this.height;
  }
}
const rect = new Rectangle(5, 10);
console.log(rect.getArea()); // 输出: 50

在上述的代码示例中,Rectangle类有一个构造函数,它接受width和height参数,并将它们分别赋值给对象的width和height属性。

四、super关键字和extends关键字

function Food(type, price){
  this.type = type;
  this.price = price;
}
Food.prototype.eat = function(){
  console.log("食物挺好吃!");
}
function Fruit(type, price, color){
  Food.call(this, type, price);
  this.color = color;
}
// 设置自己构造函数的原型
Fruit.prototype = new Food;
Fruit.prototype.constructor = Fruit;
Fruit.prototype.zhazhi = function(){
  console.log("将水果榨汁喝!");
}
let fruit = new Fruit("西瓜", 50, "绿色");
console.log(fruit); //Fruit {type: '西瓜', price: 50, color: '绿色'}
fruit.eat();    //食物挺好吃!
fruit.zhazhi(); //将水果榨汁喝!

在类继承中,当子类需要在自己的构造函数中进行一些初始化操作时,可以使用super关键字来调用父类的构造函数。确保子类实例继承了父类的属性,并且可以在子类中进行进一步的初始化操作。

extends关键字实现了JavaScript中的类继承,让子类能够继承父类中的所有属性和方法,并且能够添加自己的属性和方法进行扩展。

class Food{
  constructor(type, price){
    this.type = type;
    this.price = price;
  }
  // 父类的成员方法
  eat(){
    console.log("食物挺好吃!");
  }
  youzha(){
    console.log("油炸食物挺好吃!");
  }
}
class Fruit extends Food{
  constructor(type, price, color){
    super(type, price);
    this.color = color;
  }
  eat(){
    console.log("水果真好吃!"); //可以重写父类方法
    super.eat(); //调用父类方法
  }
  zhazhi(){
    console.log("将水果榨汁!");
    super.eat(); //调用父类方法
  }
}
let fruit = new Fruit("西瓜",50,"绿色");
console.log(fruit);
fruit.eat(); //水果真好吃! 食物挺好吃!
fruit.zhazhi(); //将水果榨汁! 食物挺好吃!
fruit.youzha(); //油炸食物挺好吃!

【ES6】中构造函数的语法糖——Class(类)

如上述代码所示,使用super(type, price)调用父类的构造函数来初始化父类的属性,子类还有一个额外的属性color。子类Fruit使用extends关键字继承了父类Food。fruit对象可以调用父类Food的youzha方法,并且改写eat方法。

五、Static静态方法和属性

function Fruit(){

}
Fruit.NAME = "水果";
Fruit.eat = function(){
  console.log("水果真好吃!");
}
Fruit.prototype.type = "西瓜";
let fruit = new Fruit();
console.log(Fruit.NAME);  //水果
console.log(Fruit.type);    //undefined
Fruit.eat(); //水果真好吃!
console.log(fruit.type);    //西瓜
console.log(fruit.NAME);  //undefined
fruit.eat(); //Uncaught TypeError: fruit.eat is not a function

如上述代码所示,在函数中,NAME属性和eat方法是构造函数Fruit上的属性和方法,实例对象访问不到,实例对象只能访问定义在函数原型上的type。只有构造函数自己才能访问到NAME属性和eat方法,但是访问不了定义在函数原型上的type。

class ShuiGuo{
  static type = "西瓜";
  static eat = function(){
    console.log("水果真好吃!");
  }
}
let shuiguo = new ShuiGuo();
console.log(ShuiGuo.type); //西瓜
ShuiGuo.eat(); //水果真好吃!
console.log(shuiguo.type); //undefined
shuiguo.eat();  //Uncaught TypeError: shuiguo.eat is not a function

在class中,可以使用static关键字定义静态方法。静态方法不需要实例化类就可以被调用,它们属于类本身而不是实例。可以通过类名去访问属性和方法,而实例对象访问不了。

六、getter和setter

在 JavaScript 的类中,我们可以使用 getter 和 setter 方法来定义属性的访问器。这允许我们在获取和设置属性值时执行自定义的逻辑。

Getter 方法用于获取属性的值,它被定义为一个没有参数的函数,并使用 get 关键字来声明。Getter 方法的命名通常与要获取的属性的名称相同。

Setter 方法用于设置属性的值,它被定义为一个带有一个参数的函数,并使用 set 关键字来声明。Setter 方法的命名通常与要设置的属性的名称相同。

class Fruit{
  get type(){
    console.log("type属性被读取了!");
    return "西瓜";
  }
  set type(newVal){
    console.log("type属性被修改了!");
  }
}
let fruit = new Fruit();
console.log(fruit.type); //type属性被读取了! 西瓜
fruit.type = "杨梅";       //type属性被修改了!

如上述代码所示,getter里的返回值就是读取fruit.type时的输出值。

七、最后的话

通过class关键字,我们可以更方便地使用面向对象的方式编写代码。constructor构造函数用于初始化对象的属性,super关键字用于调用父类的构造函数或方法。静态方法和静态属性属于类本身而不是实例,可以直接通过类名进行调用。通过灵活运用这些特性,我们可以更好地组织和管理前端代码。

能力一般,水平有限,本文可能存在纰漏或错误,如有问题欢迎大佬指正,感谢你阅读这篇文章,如果你觉得写得还行的话,不要忘记点赞、评论、收藏哦!祝生活愉快!

原文链接:https://juejin.cn/post/7245975053232472124 作者:牛哥说我不优雅

(0)
上一篇 2023年6月19日 上午10:58
下一篇 2023年6月19日 上午11:08

相关推荐

发表回复

登录后才能评论