javascript学习笔记(20)--class继承

引入

在上面的章节中我们看到了JavaScript的对象模型是基于原型实现的,特点是简单,缺点是理解起来比传统的类-实例模型要困难,最大的缺点是继承的实现需要编写大量代码,并且需要正确实现原型链

新的关键字class从ES6开始正式被引入到JavaScript中
class的目的就是让定义类更简单

class

还是先回顾一下之前的方法

function Student(name){
this.name=name;
this.hello=function(){console.log('你好');};
Student.prototype.id=1;
Student.prototype.greet=function(){console.log('i am ok');};
}

因为我们在定义类的时候主要关注两个,一个是实例,一个是prototype,而用函数的化,this定义的实例,prototype定义就不用说了
我们可以通过实例化后的对象看他身上具有的实例和prototype属性方法
在这里插入图片描述
先讲讲class的规矩
在这里插入图片描述不能直接定义函数(没有function关键字)
在这里插入图片描述也不能直接定义实例变量
在这里插入图片描述
也不能直接在prototype下定义变量(虽然之前函数可以,但其实最好还是在定义完之后再引入)
在这里插入图片描述
不能重复定义class

class里面直接引入了构造函数,并且为了方便在prototype下定义函数,我们直接 f(){};这样写就可以,就表明你的函数是在prototype下面啦,就避免了Student.prototype.f= function () {…}这样分散的代码

先上个简单的class类

 class Student { 
 constructor(name) { 
 this.name = name; 
 this.hello=function(){console.log('你好');};
 }
 id=1;
 greet(){console.log('i am ok');};
 }

在这里插入图片描述
可以看到,我们定义的函数都是在prototype下,在class里直接定义的变量也是属于实例变量,然后在constructor里定义的变量和函数其实和之前函数里的差不多,也是实例属性(其实constructor和我们前面的构造函数差不多)

最开始还没发现,其实constructor和构造函数都是一摸一样的,刚才不是说嘛,在class内部不能直接定义prototype,我们可以转移到constructor内部

class Student { 
 constructor(name) { 
 this.name = name; 
 this.hello=function(){console.log('你好');};Student.prototype.grade=1;Student.prototype.lalala=function(){console.log('啦啦啦');};
 }
 id=1;
 greet(){console.log('i am ok');};
 }
Student.prototype.grade=1;//这个放在整体定义完之后也可以

在这里插入图片描述怎么样,确实是和我们之前讲的构造函数一摸一样吧

class外部定义的实例变量(id=1)和pr函数 和construcotr里面的有什么区别吗
之前的构造函数可以直接把protype变成null,但class的prototype真的是
在这里插入图片描述改不动,但里面的内容还是可以修改的
不过跟构造函数的一样,construcotr修改了没用
在这里插入图片描述
像constroctor里面的this绑定的变量方法和外面的id又都是实例变量方法,也改不了

像是prototype下绑定的内容修改了后还是要注意新创建对象的时候重新赋值的问题

在这里插入图片描述在这里插入图片描述
所以其实没什么区别,定义到哪里都可以…都是一样的
但其实还是有一点细微的区别,如果你定义的实例化变量是需要传入参数的,就只能放在constructor里面(prototype里一般不会出现需要赋值的变量,不然那其实最后还是变成实例变量了),像如果你直接放在class的话无法传入参数的

最后,创建一个Student对象代码和前面章节完全一样

var xiaoming = new Student('小明'); 
xiaoming.hello();

class继承

用class定义对象的另一个巨大的好处是继承更方便了
想一想我们从Student派生一个PrimaryStudent需要编写的代码量,现在,原型继承的中间对象,原型对象的构造函数等等都不需要考虑了,直接通过extends来实现

 class Student { 
 constructor(name) { 
 this.name = name; 
 this.hello=function(){console.log('你好');};Student.prototype.age=1;Student.prototype.lalala=function(){console.log('啦啦啦');};
 }
 }
 
 class PrimaryStudent extends Student 
 {
  constructor(name, grade) 
 { super(name); 
 this.grade = grade;
  }
  myGrade() { alert('我的分数是' + this.grade); } }

注意PrimaryStudent的定义也是class关键字实现的,而extends则表示原型链对象来自Student
子类的构造函数可能会与父类不太相同,例如,PrimaryStudent需要name和grade两个参数,并且需要通过super(name)来调用父类的构造函数,否则父类的name属性无法正常初始化,而另一个就是我们自己新定义的变量
PrimaryStudent已经自动获得了父类Student的一系列方法,我们又在子类中定义了新的myGrade方法
在这里插入图片描述
在这里插入图片描述还是可以看出来的,Student和Primary里面定义的所有实例变量和方法都变成了实例化对象里的实例变量和方法
定义在Primary.prototype里的方法和属性和Studentprototype里的属性和方法也统统被继承了下来

好了这部分算是结束了,最后几个是js里面最复杂的了,接下来咱们正式进入浏览器 ,希望大家多多支持

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值