ES5和ES6中类的区别总结
类定义与调用的区别
在ES5中主要是通过构造函数方式和原型方式来定义一个类,但是在ES6新引入了class关键字,使之具有了正式类的能力,类(class)是ECMAScript中新的基础性语法糖结构。虽然ES6类表面上看起来可以支持正式的面向对象编程,但实际上它背后使用的仍然是原型和构造函数的概念。
使用ES5定义一个类并调用
functionPerson(name,age,job){
this.name="Totora";
this.age=19;
this.job="student";
this.sayName=function(){
console.log(this.name);
};
}
letperson=newPerson();
person.sayName();
使用ES6定义一个类并调用
ES6中有两种定义类的方式:类声明和类表达式
classPerson{
constructor(){
this.name="Totora";
this.age=19;
this.job="student";
}
sayName(){
console.log(this.name);
}
}
letperson=newPerson();
person.sayName();
//当我们使用typeof检测Person的类型时:
console.log(typeofPerson);//function,它的本质仍然是函数
在调用类时,不管是ES5还是ES6,都必须使用new操作符来进行调用,不可以直接执行。
两者区别在于:
ES5这样调用不会报错,可以正常执行(因为ES5中的类和普通函数几乎没有本质上的区别)
functionPerson(name,age,job){
this.name="Totora";
this.age=19;
this.job="student";
this.sayName=function(){
console.log(this.name);
};
}
letperson=Person();
console.log(person);//undefined
ES6会报错
classPerson{
constructor(){
this.name="Totora";
this.age=19;
this.job="student";
}
sayName(){
console.log(this.name);
}
}
letperson=Person();
console.log(person);
person.sayName();//ClassconstructorPersoncannotbeinvokedwithout'new'
变量提升
通过以下对比可以发现,当用class声明类执行时会报错,说明ES6中用class定义的类无法实现变量提升。
函数受函数作用域的限制,但是类受块作用域的限制
//变量提升
letperson=newPerson()
functionPerson(name,age,job){
this.name="Totora";
this.age=19;
this.job="student";
this.sayName=function(){
console.log(this.name);
};
}
person.sayName();//Totora
letperson=newPerson();
classPerson{
constructor(){
this.name="Totora";
this.age=19;
this.job="student";
}
sayName(){
console.log(this.name);
}
}
person.sayName();//Cannotaccess'Person'beforeinitialization
class中类的构成
类可以包含构造函数方法、实例方法、获取函数、设置函数、静态类的方法。但是空的类定义照样有效
//空类定义
classFoo{}
//有构造函数的类
classBar{
constructor(){}
}
//有获取函数的类
classBaz{
getmyBaz(){}
}
//有静态方法的类
classQux{
staticmyQux(){}
}
class中的静态方法
可以在类上定义静态方法。静态类成员在类定义中使用static关键字作为前缀,在静态成员中,this引用类自身;
与原型成员类似,静态成员每个类上只能有一个;
static声明的静态属性和方法都可以被子类继承。
classPerson{
constructor(){
//添加到this的所有内容都会存在于不同的实例上
this.locate=()=>console.log('instance',this);
}
//定义在类的原型对象上
locate(){
console.log('prototype',this);
}
//定义在类本身上
staticlocate(){
console.log('class',this);
}
}
letp=newPerson();
p.locate();//instancePerson{locate:[Function(anonymous)]}
Person.prototype.locate();//prototype{}
Person.locate();//class[classPerson]
classPerson{
staticname(){
this.job();//此处的this指向类
}
staticjob(){
console.log('Totora');//不会出现在实例中
}
job(){
console.log('student');
}
}
Person.name();//Totora
继承
ES5中的继承实质上是先创建子类的实例对象,再将父类的方法添加到this上(Parent.apply(this)),通过原型或构造函数机制来实现
ES6的继承实际上是先创建父类的实例对象this,然后再用子类的构造函数修改this。
ES6中类之间通过extends关键字,就可以继承任何拥有[[Construct]]和原型的对象,在很大程度上,这不仅i仅可以继承一个类,也可以继承普通的构造函数(保持向后兼容)
ES6中派生类的方法可以通过super关键字引用它们的原型,这个关键字只能在派生类中使用,而且仅限于类的构造函数、实例方法和静态方法的内部。在类构造函数中使用super可以调用父类构造函数。
//ES5中的继承
functionparent(a,b){
this.a=a;
this.b=b;
}
functionchild(c){
this.c=c;
}
parent.call(child,1,2);//子级来继承父级
child.prototype=newparent(1,2);
//ES6中的继承
classparent{
constructor(a,b){
this.a=a;
this.b=b;
}
parentMethods(){
returnthis.a+this.b
}
}
classchildextendsparent{
constructor(a,b,c){
super(a,b);//通过super调用父类
this.c=c;
}
childMethods(){
returnthis.c+','+super.parentMethods()//通过super实例化调用父类
}
}
constpoint=newchild(1,2,3);
console.log(point.childMethods());
总结
到此这篇关于ES5和ES6中类区别的文章就介绍到这了,更多相关ES5和ES6类的区别内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!