JavaScript只有对象,没有类的概念,生成实例对象的传统方法也是通过构造函数。ES6引入了class类概念,通过关键字class定义。
以下几点:
-
1.类的用法理解
-
2.如何为类添加新方法
-
3.constructor()方法
-
4.class的继承
1.类的用法
-
1.类实质上是一个函数,类自身指向的就是构造函数。
ES5构造函数实例用法如下:
//es5构造函数实例 function Person(name,age){ this.name=name; this.age=age; } Person.prototype.show = function() { // body... return 'my name is '+ this.name+','+this.age; }; //使用new运算符,通过构造函数创建对象 var person=new Person('xiaohua',22); console.log(person.show());//my name is xiaohua,22
es6类的用法如下:
//es6 //定义一个Person类 class Person{ //constructor是构造函数,用来接收参数 constructor(name,age){ this.name=name;//this代表实例对象 this.age=age; } //定义show方法,不可以加function关键字 show(){ return 'my name is '+ this.name+','+this.age; }; }//类的定义结束 //创建对象,代码中person是Person的实例,它的constructor方法就是Person类的原型 var person=new Person('xiaohua',22); console.log(person.show());//my name is xiaohua,22
针对es6 class写法的易错点:
-
1.在类中声明方法时,不能给该方法添加function关键字,否则会报uncaught SyntaxError错误。
-
2.方法之间不能使用逗号分隔,否则会报uncaught SyntaxError错误。
-
3.构造函数的prototype属性在es6中依然存在。
-
4.类其实就是构造函数的另一种写法。
对于3和4下面帮助理解:
-
-
2.class不存在变量提升,es6不会把类的声明提升到代码的顶部,需要先定义在使用;而ES5存在变量提升,可以先使用再定义。
例:
2.为类添加新方法
-
1.类的方法都定义在prototype对象上面,所以类的新方法可以添加在prototype对象上面。
如下:
//定义一个Person类 class Person{ //constructor是构造函数,用来接收参数 constructor(name,age){ this.name=name;//this代表实例对象 this.age=age; } //定义show方法,不可以加function关键字 show(){ return 'my name is '+ this.name+','+this.age; }; }//类的定义结束 //prototype属性增加方法 Person.prototype.showheight = function() { // body... return '我是通过prototype属性新增加的方法,方法名showheight' }; var person=new Person('xiaohua',22); //控制台输出:我是通过prototype属性新增加的方法,方法名showheight console.log(person.showheight());
由控制输出内容可知,通过prototype属性添加方法成功。
-
2.通过Object.assign方法为对象动态添加方法,可以方便的一次性添加多个方法。
语法为:
Object.assign(classname.prototype,{ //添加方法一 fun1:function(){ }, //添加方法二 fun2:function(){ }, //添加方法三 fun3:function(){ } ...... })
例如:
//定义一个Person类 class Person{ //constructor是构造函数,用来接收参数 constructor(name,age){ this.name=name;//this代表实例对象 this.age=age; } //定义show方法,不可以加function关键字 show(){ return 'my name is '+ this.name+','+this.age; }; }//类的定义结束 //通过Object.assign方法为类添加多个方法 Object.assign(Person.prototype,{ getName:function(){ return this.name; }, getAge:function(){ return this.age; } }) var person=new Person('xiaohua',22); console.log(person.getName());//xiaohua console.log(person.getAge());//22
上面代码Object.assign方法为类Person添加了getName和getAge两个方法。
3.constructor()方法
constructor()方法是类的构造函数默认的方法,通过new运算符生成对象实例时,自动调用该方法。
一个类必须有constructor()方法,如果没有显示定义,会被默认添加一个空的constructor()方法。
class Person{
//一个未定义constructor()方法的类,
//JavaScript引擎会自动为它添加一个空的constructor方法。
}
//等同于
class Person{
constructor(){
//JavaScript引擎会自动添加
}
}
4.class类的继承
类class可以通过extends关键字实现继承,而ES5要通过修改原型链实现继承,较为复杂易错难懂。
-
关键字extends,super的理解
-
extends:通过extends关键字,继承了父类的所有属性和方法。
-
super:表示父类的构造函数,用来新建父类的this对象。
-
-
继承的应用
例:
//定义一个Person类 class Person{ //constructor是构造函数,用来接收参数 constructor(name,age){ this.name=name;//this代表实例对象 this.age=age; } //定义show方法,不可以加function关键字 show(){ return this.name+' '+this.age }; }//类的定义结束 //类的继承,关键字extends,super class onePerson extends Person{ constructor(name,age,height){ super(name,age);//super调用父类的构造函数,用来新建父类的this对象 this.height=height; } show(){ return this.height+' '+super.show();//调用父类的show方法 } } //构造子类的实例 var person= new onePerson('xiaohua',22,'171cm') console.log(person.show());//171cm xiaohua 22
分析:
上面代码,子类onePerson继承了父类Person的所有方法,子类必须在constructor方法中调用super方法,否则新建实例的时候就会报错。
因为子类自己的this对象必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性与方法。然后再对其加上自己的实例属性与方法。如果不调用super方法,子类就得不到this对象。
-
ES5和ES6的继承实质
-
ES5的继承实质:
先创建子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。
-
ES6的继承实质:
先将父类实例对象的属性和方法加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。
【在子类的构造函数中,只有调用super后,才可以使用this关键字,否则报错。因为子类实例的构建基于父类,只有super方法才能调用父类实例。】
-