千家信息网

js中从原型链开始图解继承到组合继承的产生过程是怎样的

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这期内容当中小编将会给大家带来有关js中从原型链开始图解继承到组合继承的产生过程是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。于javascript原型链的
千家信息网最后更新 2026年10月31日js中从原型链开始图解继承到组合继承的产生过程是怎样的

这期内容当中小编将会给大家带来有关js中从原型链开始图解继承到组合继承的产生过程是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

于javascript原型链的层层递进查找规则,以及原型对象(prototype)的共享特性,实现继承是非常简单的事情

一、把父类的实例对象赋给子类的原型对象(prototype),可以实现继承

function Person(){ this.userName = 'ghostwu'; } Person.prototype.showUserName = function(){ return this.userName; } function Teacher (){} Teacher.prototype = new Person(); var oT = new Teacher();  console.log( oT.userName ); //ghostwu console.log( oT.showUserName() ); //ghostwu

通过把父类(Person)的一个实例赋给子类Teacher的原型对象,就可以实现继承,子类的实例就可以访问到父类的属性和方法

如果你不会画这个图,你需要去看下我的这篇文章:

[js高手之路]一步步图解javascript的原型(prototype)对象,原型链

第11行,执行oT.userName, 首先去oT对象上查找,很明显oT对象上没有任何属性,所以就顺着oT的隐式原型__proto__的指向查找到Teacher.prototype,

发现还是没有userName这个属性,继续沿着Teacher.prototype.__proto__向上查找,找到了new Person() 这个实例上面有个userName,值为ghostwu

所以停止查找,输出ghostwu.

第12行,执行oT.showUserName前面的过程同上,但是在new Person()这个实例上还是没有查找到showUserName这个方法,继续沿着new Person()的

隐式原型__proto__的指向( Person.prototype )查找,在Person.prototype上找到了showUserName这个方法,停止查找,输出ghostwu.

二、把父类的原型对象(prototype)赋给子类的原型对象(prototype),可以继承到父类的方法,但是继承不到父类的属性

function Person(){ this.userName = 'ghostwu'; } Person.prototype.showUserName = function(){ return 'Person::showUserName方法'; } function Teacher (){} Teacher.prototype = Person.prototype; var oT = new Teacher();  console.log( oT.showUserName() ); //ghostwu console.log( oT.userName ); //undefined, 没有继承到父类的userName

因为Teacher.prototype的隐式原型(__proto__)只指向Person.prototype,所以获取不到Person实例的属性

三、发生继承关系后,实例与构造函数(类)的关系判断

还是通过instanceof和isPrototypeOf判断

function Person(){ this.userName = 'ghostwu'; } Person.prototype.showUserName = function(){ return this.userName; } function Teacher (){} Teacher.prototype = new Person();  var oT = new Teacher(); console.log( oT instanceof Teacher ); //true console.log( oT instanceof Person ); //true console.log( oT instanceof Object ); //true console.log( Teacher.prototype.isPrototypeOf( oT ) ); //true console.log( Person.prototype.isPrototypeOf( oT ) ); //true console.log( Object.prototype.isPrototypeOf( oT ) ); //true

四,父类存在的方法和属性,子类可以覆盖(重写),子类没有的方法和属性,可以扩展

function Person() {} Person.prototype.showUserName = function () { console.log('Person::showUserName'); } function Teacher() { } Teacher.prototype = new Person(); Teacher.prototype.showUserName = function(){ console.log('Teacher::showUserName'); } Teacher.prototype.showAge = function(){ console.log( 22 ); } var oT = new Teacher(); oT.showUserName(); //Teacher::showUserName oT.showAge(); //22

五、重写原型对象之后,其实就是把原型对象的__proto__的指向发生了改变

原型对象prototype的__proto__的指向发生了改变,会把原本的继承关系覆盖(切断)

function Person() {} Person.prototype.showUserName = function () { console.log('Person::showUserName'); } function Teacher() {} Teacher.prototype = new Person(); Teacher.prototype = { showAge : function(){ console.log( 22 ); } } var oT = new Teacher(); oT.showAge(); //22 oT.showUserName();

上例,第7行,Teacher.prototype重写了Teacher的原型对象(prototype),原来第6行的原型对象的隐式原型(__proto__)指向就没有作用了

所以在第14行,oT.showUserName() 就会发生调用错误,因为Teacher的原型对象(prototype)的隐式原型(__proto__)不再指向父类(Person)的实例,继承关系被破坏了.

六、在继承过程中,小心处理实例的属性上引用类型的数据

function Person(){ this.skills = [ 'php', 'javascript' ]; } function Teacher (){} Teacher.prototype = new Person(); var oT1 = new Teacher(); var oT2 = new Teacher(); oT1.skills.push( 'linux' ); console.log( oT2.skills ); //php, java, linux

oT1的skills添加了一项linux数据,其他的实例都能访问到,因为其他实例中共享了skills数据,skills是一个引用类型

七、借用构造函数

为了消除引用类型影响不同的实例,可以借用构造函数,把引用类型的数据复制到每个对象上,就不会相互影响了

function Person( uName ){ this.skills = [ 'php', 'javascript' ]; this.userName = uName; } Person.prototype.showUserName = function(){ return this.userName; } function Teacher ( uName ){ Person.call( this, uName ); } var oT1 = new Teacher(); oT1.skills.push( 'linux' ); var oT2 = new Teacher(); console.log( oT2.skills ); //php,javascript console.log( oT2.showUserName() );

虽然oT1.skills添加了一项Linux,但是不会影响oT2.skills的数据,通过子类构造函数中call的方式,去借用父类的构造函数,把父类的属性复制过来,而且还能

传递参数,如第8行,但是第15行,方法调用错误,因为在构造中只复制了属性,不会复制到父类原型对象上的方法

八、组合继承(原型对象+借用构造函数)

经过以上的分析, 单一的原型继承的缺点有:

1、不能传递参数,如,

Teacher.prototype = new Person();
有些人说,小括号后面可以跟参数啊,没错,但是只要跟了参数,子类所有的实例属性,都是跟这个一样,说白了,还是传递不了参数

2、把引用类型放在原型对象上,会在不同实例上产生相互影响

单一的借用构造函数的缺点:

1、不能复制到父类的方法

刚好原型对象方式的缺点,借用构造函数可以弥补,借用构造函数的缺点,原型对象方式可以弥补,于是,就产生了一种组合继承方法:

function Person( uName ){ this.skills = [ 'php', 'javascript' ]; this.userName = uName; } Person.prototype.showUserName = function(){ return this.userName; } function Teacher ( uName ){ Person.call( this, uName ); } Teacher.prototype = new Person(); var oT1 = new Teacher( 'ghostwu' ); oT1.skills.push( 'linux' ); var oT2 = new Teacher( 'ghostwu' ); console.log( oT2.skills ); //php,javascript console.log( oT2.showUserName() ); //ghostwu

子类实例oT2的skills不会受到oT1的影响,子类的实例也能调用到父类的方法。

上述就是小编为大家分享的js中从原型链开始图解继承到组合继承的产生过程是怎样的了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

原型 对象 实例 方法 属性 子类 函数 指向 参数 数据 类型 影响 过程 组合 缺点 还是 方式 分析 不同 内容 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 伟宏互联网科技 蓝思科技飞鸽互联网 科技与互联网发展 成都互联网科技公司 华中科技大学互联网 万达互联网科技 阿里巴巴算科技企业还是互联网 随着互联网科技发展 科技与互联网哪个更好 互联网科技项目计划书材料类 河南猎农互联网科技有限公司 亳州好赞互联网科技有限公司 阿里互联网科技企业 国大互联网教育科技有限公司薪资 湖北辰鑫科技互联网 中国科技和美国互联网 兰石爱特工业互联网科技分公司 北京互联网科技类企业分布 10位科技互联网大佬 中国主要互联网科技公司 科技互联网政务服务 互联网科技公司做什么 湖南洣水互联网科技有限公司扣款 深圳国际航运科技和互联网 华夏恒生互联网科技013171 半导体行业属于互联网高科技类吗 广州有谷有贝互联网科技有限公司 互联网科技接地气 湖北辰鑫科技互联网 米泉互联网科技专业怎么样
0