博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
轻松深入理解JavaScript的继承原理
阅读量:3941 次
发布时间:2019-05-24

本文共 2867 字,大约阅读时间需要 9 分钟。

什么是继承?

继承这个词,在生活中有很多种语境,可以是继承财产,也可以是继承权利,或是继承血统,仔细想想他们有一个共同的特点就是,继承者所继承的事物均来自被继承者本身,其实JavaScript的继承也是这样的,很多编程中的思想都可以通过生活中的实例来理解

JavaScript的继承体现

那么在JavaScript中是怎么实现继承的呢?

类式继承

首先介绍第一种叫类式继承

// 类式继承function Father() {
this.FatherValue = true}// 为 Father添加一个共有方法:Father.prototype.getFatherValue = function() {
return this.FatherValue}function Son() {
this.sonValue = false}// sun 继承 father Son.prototype = new Father()Son.prototype.getSonValue = function() {
return this.sonValue}

核心代码 :Son.prototype = new Father()

我们在实例化一个父类的时候。新创建的对象复制了父亲的构造函数里的属性和方法并且将原型_ _ proto_ _指向了父亲的原型对象,这样就拥有了父亲的原型对象上的属性和方法,并且这个新创建的对象可以直接访问到父亲原型对象上的属性与方法。

关于原型和原型链我是这样理解的

在这里插入图片描述
所以Son一层层找上去是可以访问到FatherValue的

但是这种类式的继承有个缺点

  1. 如果父类中的共有属性是引用类型,就会在子类中被所有实例共用,所以子类的实例更改子类原型从父类构造函数中继承来的共有属性就会直接影响其他子类
  2. 无法向父类传递参数,无法在实例化父类的时候对父类的构造函数内的属性进行初始化

构造函数继承

为了解决上述问题,所以有了构造函数继承

function Father(id){
this.skill = ['read','run','speak'] this.id = id}Father.prototype.showSkills = function(){
console.log(this.skill)}function Son(id){
// 继承 父类 Father.call(this,id)}

核心代码: Father.call(this,id)

call改变了函数的作用环境,将子类中的变量在父类中再执行一遍

缺点:

这种形式的继承创建出来的实例都会单独拥有一份不能共用

不能够实现代码复用,是不优雅的

组合继承

为了再一次对继承进行优化,我们把两种方法结合起来

function Father(id){
this.skill = ['read','run','speak'] this.id = id}Father.prototype.showSkills = function(){
console.log(this.skill)}function Son(id , hobby){
// 继承 父类id属性 Father.call(this,id) this.hobby = hobby}// 子类原型继承父类Son.prototype = new Father()Son.prototype.getHobby = function(){
console.log(this.hobby)}

虽然上述的问题得到了基本解决,但是在使用构造函数继承时执行了一遍父类的构造函数,在实现子类的原型的类式继承的时候又调用了一遍父类的构造函数,调用了两遍,不够优雅

原型式继承

function inheritObj(o) {
//声明一个过渡函数对象 function F() {
} // 过渡对象的原型继承父对象 F.prototype = o // 返回过渡对象的一个实例,该实例的原型继承了父对象 return new F()}

在原型式继承之后,还有寄生式继承,以及寄生组合式继承,这里就不再赘述了,大家可以查阅资料作为拓展内容,接下来介绍一下继承函数的封装

圣杯模式

/*            **  圣杯模式:            **  定义 F()作为中间层,用于实现Target 的个性化定制,并且不会影响到Father 的原型            **  uber( super 是保留字,故此处不使用) 找到自己的超类              */         function inherit(Target ,Origin){
function F(){
}; F.prototype = Origin.prototype; Target.prototype = new F(); Target.prototype.constuctor = Target; Target.prototype.uber = Origin.prototype; }

圣杯模式进化版

/*            **  此方法 来自于:YUI3 (  雅虎  )            **  利用了函数闭包的性质            **  var F = function () {} 成为了一个私有变量            **  此方法更符合语义化  更加的高明            */             var inherit = (function(){
var F = function(){
}; return function(Target,Origin){
F.prototype = Origin.prototype; Target.prototype = new F(); Target.prototype.constuctor = Target; Target.prototype.uber = Origin.prototype; } }());

转载地址:http://qjnwi.baihongyu.com/

你可能感兴趣的文章
厦大06应用金融硕士研究生推荐精读书目
查看>>
《越人歌》-诗经
查看>>
Jetty嵌入式服务器的JNDI快速配置指南
查看>>
夜, 北京
查看>>
图示ExtJS商业智能的仪表盘配置系统 - (Season 1)
查看>>
MAC 显示隐藏文件的方法
查看>>
Ext.Ajax教程,及Get和Post请求的使用拾遗
查看>>
Mac下配制Maven过程
查看>>
Mac下的Eclipse3.4反编译插件
查看>>
Mac截图快捷键大全
查看>>
扩展Spring Security-用户密码自定义加密的快速实现
查看>>
Log4j异步日志简明配制
查看>>
扩展Spring Security-国际化终极配制
查看>>
在Mac OS系统下得Linux虚拟机中安装Confluence3
查看>>
在Eclipse中调试Jetty应用的配置(XML配置文件方式)
查看>>
Ext-3.1.0下组件中按钮居中问题的记要
查看>>
MacOS下使用screen命令运行后台程序
查看>>
东北人的幽默,《红男绿女》中经典对白,看过的人都明白
查看>>
印象后海
查看>>
看了这54句,你就看懂了人性
查看>>