引言
按照构造函数形式创建类,不仅仅和编写普通的函数过于相似,而且代码并不容易理解。在ES6(ECMAScript2015)新的标准中使用了class关键字来直接定义类。但是类本质上依然是前面所讲的构造函数、原型链的语法糖而已。所以学好了构造函数、原型链更有利于我们理解类的概念和继承关系。
那么如何来使用class来定义一个类呢?
类的声明
//类的声明
class Person{
}
//babel
//类的表达式
// var Animal = class{
// }
可以观察一下类的特点,它也是有原型的。
//类的声明
class Person{
}
//babel
//类的表达式
// var Animal = class{
// }
//研究一下类的特点
console.log(Person.prototype); //还是有原型的 {}
console.log(Person.prototype.__proto__); //Object: null prototype] {}
console.log(Person.prototype.constructor); //[class Person]也是指向当前对象本身的
console.log(typeof Person); //function typeof是不会返回class的,它返回的很多东西都是固定的
类的构造方法
通过类的构造方法,可以把值传入类中。这里和构造函数有些许不同,是依靠constructor
来实现的。
//类的声明和构造函数是分开的
class Person{
//类的构造方法
//注意:一个类只能有一个构造函数,不能做类的重载
//1.在内存中创建一个对象
//2.将类的原型portotype,赋值给我们创建出来的对象 moni.__proto__ = Person.prototype
//3.将我们对象赋值给函数的this this = moni
//4.执行函数体中的代码
//5.自动返回创建出来的对象
constructor(name,age){ //和prototype的那个constructor没关系
this.name = name
this.age = age
}
}
类中方法的定义
类中的方法主要有普通方法,访问器方法,静态方法等。访问器方法也就是get
,set
。静态方法支持直接通过类名来访问(并不需要创建一个对象实例)。
var names = ['aaa','bbb','ccc']
class Person{
constructor(name,age){
this.name = name
this.age = age
this._address = "广州市"
}
//这里的函数都会进行共享的,它们是放到原型上面的
eating(){
console.log(this.name+"eating");
}
running(){
console.log(this.name+'running');
}
//类的访问器方法(get,set),这个其实用的也不是特别多
get address(){
console.log("拦截访问操作");
return this._address
}
set address(newAddress){
console.log("拦截设置操作");
this._address = newAddress
}
//类的静态方法
//创建出来的对象进行访问的
//var p = new Person()
//p.xxx
//静态方法可以直接通过类名来访问
//Person.createPerson()
static randomPerson(){
var nameIndex = Math.floor(Math.random() * names.length)
var name = names[nameIndex]
var age = Math.floor(Math.random() * 100)
return new Person(name,age)
}
}
var p = new Person('harry',18)
p.running()
console.log(p.address);
p.address = "北京市"
console.log(p.address);
// var p1 = Person.randomPerson
for(var i = 0 ; i < 50; i++){
console.log(Person.randomPerson());
}
class中实现继承
下面是案例代码(代码1):
class Person{
constructor(name,age){
this.name = name
this.age = age
}
running(){
console.log(this.name + 'is runing~');
}
//重写的方法,存在需要追加功能的情况
personMethod(){
console.log('处理逻辑1');
console.log('处理逻辑2');
console.log('处理逻辑3');
}
static studentMethod(){
console.log('person static method');
}
}
class Student extends Person{
//JS引擎在解析子类的时候就有要求,如果我们有实现继承
//那么子类的构造方法中,在使用this之前。或者在return 之前。
constructor(name,age,sno){
super(name,age) //交给父类处理
this.sno = sno
}
studying(){
console.log(this.name + 'is studying~');
}
//@overwite
personMethod(){
super.personMethod()
console.log('处理逻辑4');
}
staticMethod(){
console.log('student static method');
}
}
var stu = new Student('hgx',18,111)
console.log(stu);
stu.running()
stu.studying()
stu.personMethod()
super关键字
子类可以继承父类,并且可以重写父类的方法。这里要重点介绍一下super
和这个关键字的作用。
作用1
JS引擎在解析子类的时候就有要求,如果我们有实现继承那么子类的构造方法中,在使用this之前或者在return 之前必须通过super关键字调用一下父类的构造方法。
作用2
如果想要子类重写的方法中追加父类的功能,可以通过super调用父类的方法。
来自本人掘金文章 https://juejin.cn/post/7111919038346821645/**## 引言
按照构造函数形式创建类,不仅仅和编写普通的函数过于相似,而且代码并不容易理解。在ES6(ECMAScript2015)新的标准中使用了class关键字来直接定义类。但是类本质上依然是前面所讲的构造函数、原型链的语法糖而已。所以学好了构造函数、原型链更有利于我们理解类的概念和继承关系。
那么如何来使用class来定义一个类呢?
类的声明
//类的声明
class Person{
}
//babel
//类的表达式
// var Animal = class{
// }
可以观察一下类的特点,它也是有原型的。
//类的声明
class Person{
}
//babel
//类的表达式
// var Animal = class{
// }
//研究一下类的特点
console.log(Person.prototype); //还是有原型的 {}
console.log(Person.prototype.__proto__); //Object: null prototype] {}
console.log(Person.prototype.constructor); //[class Person]也是指向当前对象本身的
console.log(typeof Person); //function typeof是不会返回class的,它返回的很多东西都是固定的
类的构造方法
通过类的构造方法,可以把值传入类中。这里和构造函数有些许不同,是依靠constructor
来实现的。
//类的声明和构造函数是分开的
class Person{
//类的构造方法
//注意:一个类只能有一个构造函数,不能做类的重载
//1.在内存中创建一个对象
//2.将类的原型portotype,赋值给我们创建出来的对象 moni.__proto__ = Person.prototype
//3.将我们对象赋值给函数的this this = moni
//4.执行函数体中的代码
//5.自动返回创建出来的对象
constructor(name,age){ //和prototype的那个constructor没关系
this.name = name
this.age = age
}
}
类中方法的定义
类中的方法主要有普通方法,访问器方法,静态方法等。访问器方法也就是get
,set
。静态方法支持直接通过类名来访问(并不需要创建一个对象实例)。
var names = ['aaa','bbb','ccc']
class Person{
constructor(name,age){
this.name = name
this.age = age
this._address = "广州市"
}
//这里的函数都会进行共享的,它们是放到原型上面的
eating(){
console.log(this.name+"eating");
}
running(){
console.log(this.name+'running');
}
//类的访问器方法(get,set),这个其实用的也不是特别多
get address(){
console.log("拦截访问操作");
return this._address
}
set address(newAddress){
console.log("拦截设置操作");
this._address = newAddress
}
//类的静态方法
//创建出来的对象进行访问的
//var p = new Person()
//p.xxx
//静态方法可以直接通过类名来访问
//Person.createPerson()
static randomPerson(){
var nameIndex = Math.floor(Math.random() * names.length)
var name = names[nameIndex]
var age = Math.floor(Math.random() * 100)
return new Person(name,age)
}
}
var p = new Person('harry',18)
p.running()
console.log(p.address);
p.address = "北京市"
console.log(p.address);
// var p1 = Person.randomPerson
for(var i = 0 ; i < 50; i++){
console.log(Person.randomPerson());
}
class中实现继承
下面是案例代码(代码1):
class Person{
constructor(name,age){
this.name = name
this.age = age
}
running(){
console.log(this.name + 'is runing~');
}
//重写的方法,存在需要追加功能的情况
personMethod(){
console.log('处理逻辑1');
console.log('处理逻辑2');
console.log('处理逻辑3');
}
static studentMethod(){
console.log('person static method');
}
}
class Student extends Person{
//JS引擎在解析子类的时候就有要求,如果我们有实现继承
//那么子类的构造方法中,在使用this之前。或者在return 之前。
constructor(name,age,sno){
super(name,age) //交给父类处理
this.sno = sno
}
studying(){
console.log(this.name + 'is studying~');
}
//@overwite
personMethod(){
super.personMethod()
console.log('处理逻辑4');
}
staticMethod(){
console.log('student static method');
}
}
var stu = new Student('hgx',18,111)
console.log(stu);
stu.running()
stu.studying()
stu.personMethod()
super关键字
子类可以继承父类,并且可以重写父类的方法。这里要重点介绍一下super
和这个关键字的作用。
作用1
JS引擎在解析子类的时候就有要求,如果我们有实现继承那么子类的构造方法中,在使用this之前或者在return 之前必须通过super关键字调用一下父类的构造方法。
作用2
如果想要子类重写的方法中追加父类的功能,可以通过super调用父类的方法。
JS中创建类继承自内置类
比如我要自定义一个方法,返回数组的第一个元素,这个是内置类Array里没有的方法。我可以创建一个类继承于Array这个内部类。代码如下
// 比如我要自定义一个方法,返回数组的第一个元素
class HGXArray extends Array{
//自定义的方法
firstItem(){
//这里的this是构造类HGXArray(3) [ 1, 2, 3]
return this[0]
}
}
var arr = new HGXArray(1,2,3)
console.log(arr.firstItem()); //1
mixin混入函数(实现多继承)
JS是单继承的,一个类只能有一个父类,如果要实现多继承就得用到mixin混入函数。这个mixin混入函数里面好像只能写方法进去,无法继承父类属性,写constructor进去会报错。(研究完这个问题我会更新文档)下面是案例代码:
class Person{
constructor(name,age){
this.name = name
this.age = age
}
sleep(){
console.log('我会睡');
}
}
function mixinRunner(BaseClass){
class NewClass extends BaseClass{
running(){
console.log('在跑步');
}
}
return NewClass
}
function mixinEater(BaseClass){
return class extends BaseClass{
eating(){
console.log('eater');
}
}
}
let NewStudent = mixinEater(mixinRunner(Person))
//这一步不能忘记,新建对象
let ns = new NewStudent('harry',20)
console.log(ns.name);
ns.sleep()
ns.eating()
ns.running()
来自本人掘金文章 https://juejin.cn/post/7111919038346821645/**