继承是面向对象中一个比较核心的概念. ES6 class 的继承与 java 的继承大同小异, 如果学过 java 的小伙伴应该很容易理解, 都是通过 extends 关键字继承. 相较于 ES5 当中通过原型链继承要清晰和方便许多. 先上代码:
- class Cucurbit{constructor(name,color){
- console.log("farther")
- this.name=name;
- this.color=color;
- }
- say(){
- console.log("我的名字叫"+this.name+"我是"+this.color+"颜色的");
- }
- }
- class First extends Cucurbit{
- constructor(name,color){
- super(name,color);// 调用父类的 constructor(name,color)
- }
- say(){
- console.log("我是 child");
- super.say();
- }
- }
- var wa=new First("大娃","红色");
- wa.say();
输出:
farther
我是 child
我的名字叫大娃我是红色颜色的
上面代码中, 子类的 constructor 方法和 say 方法中, 都出现了 super 关键字, 它在这里表示父类的构造函数, 用来新建父类的 this 对象.
子类必须在 constructor 方法中调用 super 方法, 之后才能使用 this 关键字, 否则新建实例时会报错. 这是因为子类没有自己的 this 对象, 而是继承父类的 this 对象. 如果不调用 super 方法, 子类就得不到 this 对象. 在这一点上 ES5 的继承与 ES6 正好相反, ES5 先创建自己的 this 对象然后再将父类的属性方法添加到自己的 this 当中.
如果子类 First 没有显式的定义 constructor, 那么下面的代码将被默认添加 (不信可以尝试下, 哈). 换言之, 如果 constructor 函数中只有 super 的话, 该 constructor 函数可以省略.
- constructor(name,color){
- super(name,color);// 调用父类的 constructor(name,color)
- }
总结 super 在子类中一般有三种作用
作为父类的构造函数调用 (已说明)
在普通方法中, 作为父类的实例调用 (已说明)
在静态方法中, 作为父类调用 (下篇文章会做介绍)
实例
创建一个 tab 切换, 页面中有三个按钮内容分别为 "中","日","韩". 要求点击按钮, 按钮以及切换的内容的背景颜色分别会变为红, 黄, 绿.
首先创建一个 tab.html 页面, 内容为:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title > 切换 </title>
- <style>
- #country input{
- margin:10px;
- padding:10px;
- }
- #country div{
- width:300px;
- height:300px;
- }
- </style>
- </head>
- <body>
- <div id="country">
- <input type="button" value="中">
- <input type="button" value="日">
- <input type="button" value="韩">
- <div > 中国 </div>
- <div > 日本 </div>
- <div > 韩国 </div>
- </div>
- </body>
- <script src="tag.js"></script>
- <script>
- new Tag("#country");
- </script>
- </html>
然后创建一个 tag.js, 内容为:
- class Tag{
- constructor(id){
- this.id=document.querySelector(id);
- this.btn=this.id.querySelectorAll("input");
- this.div=this.id.querySelectorAll("div");
- this.colorArr=["red","yellow","green"];
- this.index=0;// 显示元素的下标.
- this.init();
- }
- init(){// 初始化
- this.hide();
- this.show();
- // 给按钮增加事件
- for(let i=0;i<this.btn.length;i++){
- this.btn[i].onclick=function(){
- this.index=i;
- this.hide();
- this.show();
- }.bind(this)
- }
- }
- hide(){// 隐藏 DIV, 去除按钮背景色
- for(var i=0;i<this.btn.length;i++){
- this.btn[i].style.background=null;
- this.div[i].style.display="none";
- }
- }
- show(){// 显示指定的 DIV, 按钮与 DIV 的背景颜色进行设置
- this.div[this.index].style.display="block";// 将 DIV 进行显示
- // 按钮与 DIV 的背景颜色进行设置
- this.div[this.index].style.background=this.btn[this.index].style.background=this.colorArr[this.index];
- }
- }
示例到现在还没有用到 ES6 的继承啊, 别急! 咱们再加个需求, 在上面的切换示例基础上, 再加一个内容为 "娱乐","体育","财经" 的切换. 该切换需要在原来可点击的基础上实现自动切换功能, 以及点击页面空白区域也可实现切换.
将 tag.html 页面修改为:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title > 切换 </title>
- <style>
- #country input,#news input{
- margin:10px;
- padding:10px;
- }
- #country div,#news div{
- width:300px;
- height:300px;
- }
- </style>
- </head>
- <body>
- <div id="country">
- <input type="button" value="中">
- <input type="button" value="日">
- <input type="button" value="韩">
- <div > 中国 </div>
- <div > 日本 </div>
- <div > 韩国 </div>
- </div>
- <div id="news">
- <input type="button" value="娱乐">
- <input type="button" value="财经">
- <input type="button" value="体育">
- <div > 娱乐 </div>
- <div > 财经 </div>
- <div > 体育 </div>
- </div>
- </body>
- <script src="tag.js"></script>
- <script>
- new Tag({
- id:"#country",
- index:1,
- colorArr:["red","green","blue"]
- });
- new autoTag({
- id:"#news",
- index:2,
- colorArr:["black","pink","purple"]
- });
- </script>
- </html>
将 tag.js 修改为:
- class Tag{
- constructor(obj){
- this.id=document.querySelector(obj.id);
- this.btn=this.id.querySelectorAll("input");
- this.div=this.id.querySelectorAll("div");
- this.colorArr=obj.colorArr;
- this.index=obj.index;// 显示元素的下标.
- this.init();
- }
- init(){// 初始化
- this.hide();
- this.show();
- var that=this;
- // 给按钮增加事件
- for(let i=0;i<this.btn.length;i++){
- this.btn[i].onclick=function(ev){
- this.index=i;
- this.hide();
- this.show();
- ev.cancelBubble=true;
- }.bind(this)
- }
- }
- hide(){// 隐藏 DIV, 去除按钮背景色
- for(var i=0;i<this.btn.length;i++){
- this.btn[i].style.background=null;
- this.div[i].style.display="none";
- }
- }
- show(){// 显示指定的 DIV, 按钮与 DIV 的背景颜色进行设置
- this.div[this.index].style.display="block";// 将 DIV 进行显示
- // 按钮与 DIV 的背景颜色进行设置
- this.div[this.index].style.background=this.btn[this.index].style.background=this.colorArr[this.index];
- }
- }
- class autoTag extends Tag{
- constructor(id){
- super(id);
- this.autoInit();
- }
- autoInit(){
- document.body.onclick=this.change.bind(this);
- setInterval(this.change.bind(this),5000)
- }
- change(){
- this.index+=1;
- if(this.index>=this.btn.length)
- this.index=0;
- this.hide();
- this.show();
- }
- }
来源: http://www.jianshu.com/p/0aa8c9c52f38