ES6里的类(Class)不会用?看完这篇你就会了!

写在前面

  • 本篇文章旨在让读者快速入门ES6中关于类的相关运用,关于在ES5中如何实现近类结构等问题不在此过多讲解。
  • 默认读者掌握关于面向对象的基本知识,并了解其他面向对象语言中的类的概念。

类的声明

  • 基本语法
    要声明一个类,首先打出class关键字,然后是类的名字,后面的部分跟声明一个对象类似,但是并不需要用 逗号 隔开各个部分。
    举个栗子:
class FoodClass{
	//构造函数,constructor是保留字,constructor构造函数是可以缺省的
	constructor(name){
		this.name = name;
	}
	showName(){
		console.log(this.name);
		FoodClass = 1;//报错,不能在类中修改类名所指向的内容
	}
}

let food = new FoodClass("炒米粉");
food.showName();//输出"炒米粉"
console.log(food instanceof FoodClass);//true
console.log(typeof FoodClass);//"function"

在类的声明语法里面,有且仅有一个保留方法名 constructor ,也就是我们熟悉的构造函数,这个构造函数是可以缺省的。
值得一提的是,构造函数中创建的属性是私有属性,因此我们可以十分方便地在构造函数中创建所有需要的私有属性,这样就能在一个地方控制所有的私有属性。私有属性是实例中的属性,不会出现在 原型 上,且只能在类的构造函数中被创建。

上面这段话能帮你更好地理解构造函数,如果看不懂也没有关系,并不影响你使用它。

类实际上是一个具有构造方法的函数,这点在上面代码片的最后一行得到了体现。

  • 类的一些特性
    ① 我们都知道函数声明是可以被提升的,但是类的声明与let和const类似,是不能被提升的,在执行声明语句之前,它们会存在于临时死区(TDZ)中。关于这点可以参考一下 这篇文章
    ②类声明中的所有代码都会运行在严格模式下,而且不能让它脱离严格模式运行。
    ③使用new以外的方式调用类的构造函数会报错。
    ④类的名字在类中是个常量,不能修改,否则会报错。这点在上面的代码片中得到了体现。
    ⑤类可以作为一个参数传入函数,也可以作为函数的返回值。

类表达式

如同普通函数一样,类也有两种存在形式:声明形式和表达式形式。

声明形式:

class Aclass{
……
} 
let a = new Aclass("构造函数的参数");

表达式形式:

let Bclass = class{
……
}
let b = new Blcass("构造函数的参数");
  • 基本语法
    用表达式形式来定义一个类,不需要将标识符写在class后面。在功能上,类表达式和类声明是等价的。
    除了编写语法稍有不同以外,他们的区别就在于类声明的name属性值为类名,类表达式的name属性值是一个空字符串。比方说像下面的这个栗子中,FoodClass.name的值为空字符串,但是在上文中类声明的栗子里,FoodClass.name的值为"FoodClass"。
let FoodClass = class{
	//构造函数,constructor是保留字,constructor构造函数是可以缺省的
	constructor(name){
		this.name = name;
	}
	showName(){
		console.log(this.name);
		FoodClass = 1;//报错,不能在类中修改类名所指向的内容
	}
};

let food = new FoodClass("炒米粉");
food.showName();//输出"炒米粉"
console.log(food instanceof FoodClass);//true
console.log(typeof FoodClass);//"function"
  • 命名类表达式(此知识点仅了解即可)
    在上文的栗子中,我们定义的类表达式都是匿名的,我们可以给类的表达式进行命名。
    举个栗子:
    let FoodClass = FoodClass2{
    	……
    };
    
    在这个栗子中,我们给这个类命名为FoodClass2,FoodClass2这个标识符只存在于类定义中,因此typeof FoodClass2的值是undefined。这样做就使得我们可以在类的定义中使用FoodClass标识符,因为类名变成了FoodClass2。

类的静态方法

如同大多数其他语言的静态方法一样,ES6中定义静态方法的标识符也是 static ,static可以修饰类中 除了构造方法 的所有其他方法。
举个栗子:

	class FoodClass{
		constructor(name){
			this.name = name;
		}
		showName(){
			console.log(this.name);
		}
		static create(name){
			return new FoodClass(name);
		}
		static showName2(){
			console.log(this.name);
		}
	}

	let food = new FoodClass("炒米粉");
	let food2 = FoodClass.create("炒鸡蛋");
	food.showName();//炒米粉
	food2.showName();//炒鸡蛋
	food.showName2();//报错:food.showName2 is not a function.

在这个栗子中,我们用静态方法create()创建了food2,在这里,静态方法create起到了跟构造函数一样的作用。
静态方法是不可以在实例中访问的,必须要在类中访问静态方法,上面代码片的最后一行代码中我们尝试在实例中访问静态方法,结果报错。

类的继承和方法重写

与大多数其他面向对象语言一样,ES6中类的继承也是通过关键字extends来实现。
举个栗子:

	class chaomifen{
		constructor(weight){
			this.weight = weight;
		}
		chao(){
			console.log(`你的${this.weight}斤米粉炒好了,趁热吃!`)
		}
	}
	class chaojidan extends chaomifen{
		constructor(weight){
			super(weight);//super()方法用于访问基类的构造函数
		}
		chao(){
			console.log(`你的${this.weight}斤鸡蛋炒好了,趁热吃!`)
		}
	}
	let 炒鸡蛋 = new chaojidan(2);
	console.log(炒鸡蛋.chao());//输出:"你的2斤鸡蛋炒好了,趁热吃!"

在这个栗子中,chaojidan这个类继承了chaomifen这个类,也就是说chaomifen是chaojidan的基类,chaojidan是chaomifen的子类,也叫派生类。
super()方法用于调用基类的构造函数,chaojidan的构造函数中就用super()调用了chaomifen的构造函数。

在这里要强调几个点:1.如果子类中定义了构造函数,那么构造函数中必须要调用super(),否则会报错,如果不使用构造函数,那么创建新的实例时,系统会自动调用super()并传入所有参数。2.如果一个类不是子类,那么尝试在构造函数中调用super()会报错,这很好理解,因为它没有基类。

在上面的代码片中我们可以看到,chaomifen已经有一个chao()方法了,正常来说chaojidan会继承基类的chao()方法,而chaojidan又在类定义中声明了一个新的chao()方法,这时候在chaojidan()中的chao()方法会覆盖掉继承自基类的chao()方法,这就是类的方法重写。这点与其他面向对象语言中的方法重写表现一致,在这就不花太多篇幅讲解了。

值得一提的是,静态方法也能被正常继承。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值