一入前端深似海,从此红尘是路人系列第一弹之浅析JavaScript继承
继承算是JavaScript中的一大难点也是必须掌握的知识点。接下来我会列举一些我们常见的继承并给出对应一些的code方便大家理解。
1.类式继承,既子类原型继承父类实例化。但是当我利用new关键字实例化子类的时候,当我改变子类继承到父类属性的时候,会污染到再次实例化的子类它所继承到的属性。具体如下
function SuperClass(){ this.superValue = true; this.languages= ['JS','JAVA']; } SuperClass.prototype.getSuperValue = function(){ return this.superValue; } function SubClass(){ this.subValue = false; } SubClass.prototype = new SuperClass(); SubClass.prototype.getSubValue = function(){ return this.subValue; } var sub = new SubClass(); console.log(sub.getSuperValue()); console.log(sub.getSubValue()); console.log(sub instanceof SuperClass); //true console.log(sub instanceof SubClass); //true console.log(SubClass instanceof SuperClass); //false console.log(SubClass.prototype instanceof SuperClass); //true console.log(sub.languages) //['JS','JAVA'] sub.languages.push('HTML'); var sub1 = new SubClass(); console.log(sub1.languages); //['JS','JAVA','HTML']
2.构造函数继承,即在子类构造函数中利用call()更改作用域,将子类变量在父类中执行一遍,从而完成继承。该继承方式只能继承父类构造函数中的属性和方法,并不能直接继承到父类原型。 function SuperClass(id,books){ this.id = id; this.books = ['JS','JAVA']; } SuperClass.prototype.showBooks = function(){ return this.books; } function SubClass(id,books){ SuperClass.call(this,id,books) } var sub = new SubClass(); sub.books.push('CSS'); console.log(sub.books); //['JS','JAVA','CSS'] var sub1 = new SubClass('superClass'); console.log(sub1.books); //['JS','JAVA'] console.log(sub.showBooks()); //Uncaught TypeError: sub.showBooks is not a function
3.组合继承,即将类式继承和构造函数继承进行功能的结合,形成一个更为优良的继承方式。该继承结合了类式继承和构造函数继承,即继承了父类原型,又继承了父类构造函数中的属性和方法。这样的好处就是在用new关键字实例化一个子类的时候改变该子类继承到的属性,不会影响下一个实例化的子类继承到的属性。但是该继承方式的缺点就是子类原型继承父类实例化的时候,也会跑一次父类的构造函数。
function SuperClass(name){ this.name = name; this.books = ['JS','JAVA']; } SuperClass.prototype.getName = function(){ return this.name; } function SubClass(name,time){ SuperClass.call(this,name); this.time = time; } SubClass.prototype = new SuperClass('superClass'); SubClass.prototype.getTime = function(){ return this.time; } var sub = new SubClass('superClass'); sub.books.push('CSS'); console.log(sub.books); //['JS','JAVA','CSS'] console.log(sub.getName()); //superClass var sub1 = new SubClass('superClass'); console.log(sub1.books); //['JS','JAVA']
4.原型式继承,它是对类式继承的一个封装,在原型式继承中会声明一个过渡对象,为的就是创建要返回的新的实例化对象。这里由于F过渡类的构造函数没有内容,所以开销比较小,使用起来也比较方便。但还是有着类式继承一样的问题。 function inheritObject(o){ //声明一个过渡函数 function F(){} //过渡对象的原型继承父对象 F.prototype = o; return new F(); } var book = { name:'js book', alikeBook:['css book','html book'] } var newBook = inheritObject(book); newBook.name = 'ajax book'; newBook.alikeBook.push('xml book'); var otherBook = inheritObject(book); otherBook.name = 'flash book'; otherBook.alikeBook.push('as book'); console.log(newBook.name); //ajax book console.log(newBook.alikeBook); //['css book','html book','xml book','as book'] console.log(otherBook.name); //flash book console.log(otherBook.alikeBook); //['css book','html book','xml book','as book'] console.log(book.name); //js book console.log(book.alikeBook); //['css book','html book','xml book','as book']
5.寄生式继承,它是对原型继承的第二次封装,让新创建的对象不仅仅有父类中的属性和方法而且还可以添加新的属性和方法。 //声明基对象 function inheritObject(o){ //声明一个过渡函数 function F(){} //过渡对象的原型继承父对象 F.prototype = o; return new F(); } var book = { name:'js book', alikeBook:['css book','html book'] } function createBook(obj){ //通过原型继承方式创建对象 var o = new inheritObject(obj); //拓展新对象 o.getName = function(){ console.log(this.name); }; //返回拓展后的新对象 return o; }
6.寄生组合式继承,它将寄生式继承和构造函数继承进行结合,形成一个完美的继承方式。
/** * 寄生式继承 继承原型 * 传递参数 subClass 子类 * 传递参数 superClass 父类 */ function inheritObject(o){ //声明一个过渡函数 function F(){} //过渡对象的原型继承父对象 F.prototype = o; return new F(); } function inheritPrototype(subClass,superClass){ //复制一份父类的原型副本保存在变量 var p = inheritObject(superClass.prototype); //修正因为重写子类原型导致子类的constructor指向父类 p.constructor = subClass; //设置子类的原型 subClass.prototype = p; } //定义父类 function SuperClass(name){ this.name = name; this.colors = ['red','blue']; } //定义父类原型方法 SuperClass.prototype.getName = function(){ return this.name; } //定义子类 function SubClass(name,time){ //构造函数继承 SuperClass.call(this,name); //子类新增属性 this.time = time; } //寄生式继承父类原型 inheritPrototype(SubClass,SuperClass); //子类新增原型方法 SubClass.prototype.getTime =function(){ return this.time; } var test1 = new SubClass('js book',2014); var test2 = new SubClass('csc book',2013); test1.colors.push('black'); console.log(test1.colors); //['red','blue','black'] console.log(test2.colors); //['red','blue'] console.log(test2.getName()); console.log(test2.getTime());
至此,最终完美的寄生组合式继承便由此诞生了。
此篇文章只是我个人的一些见解,希望可以帮助到一些对于继承还比较模糊的小伙伴们。当然,如果有小伙伴觉着哪里有问题,欢迎指出,大家一起探讨交流。
原文发布时间为:2016年09月10日
原文作者: qiangdada
本文来源:开源中国 如需转载请联系原作者

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
redis慢查询日志,php安装redis扩展,redis存储session,redis主从配置
redis慢查询日志,php安装redis扩展,redis存储session,redis主从配置 redis慢查询日志 和mysql一样redis也有慢查询日志,redis的慢查询日志默认是开启的。 针对慢查询日志,主要是设置两个参数,一个是执行时长,单位是微秒,另一个是慢查询日志的长度。当一个新的命令被写入日志时,最老的一条会从命令日志队列中被移除。 编辑配置文件,文件中搜素slowlog,可以设置以下几个参数,一般情况下保持默认即可: [root@localhost ~]# vim /etc/redis.conf slowlog-log-slower-than 1000 //单位ms,表示慢于1000ms则记录日志 slowlog-max-len 128 //定义日志长度,表示最多存128条 修改完后要重启redis服务: killall redis-server redis-server /etc/redis.conf 然后在redis的命令行中可以使用以下命令查看相应的慢查询日志信息 slowlog get //列出所有的慢查询日志 slowlog get 2 //只列出2条 ...
- 下一篇
一入前端深似海,从此红尘是路人系列第二弹之如何简单粗暴的编写出一个属于自己的插件
作为一个刚入行不久的web前端工程师,虽然经验不多,但是基于本人的性格,有自己掌握的并且认为比较好玩比较高大上的东西当然是要献给大家的。此博客发表后也希望可以帮到一些还在为插件编写徘徊的兄弟们。 1、首先先来一段我自己项目开发中最喜欢的插件的写法,也是一个比较经典的jQuery插件写法。 //闭包限定命名空间 ;(function($,doc,win){ var Plugins = function(options){ this.setting = { //这里是插件中各种参数,各种属性配置 pluginsID: '', alertHtml: '' }; /** * 这里如果有懂JavaScript设计模式的朋友们应该知道 * 这是比较常见的适配器模式,通过适配器来适配传入的参数 */ for(var i in this.setting){ this.setting[i] = options[i] || this.setting[i]; } //或者通过$.extend(this.setting,options)进行适配,不过这样可能会多添加属性,小伙伴们可以自行去测试 //调用插件方...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS关闭SELinux安全模块
- Linux系统CentOS6、CentOS7手动修改IP地址
- Windows10,CentOS7,CentOS8安装Nodejs环境
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Red5直播服务器,属于Java语言的直播服务器