-
2020-08-20 17:14:49
寄生式继承是与原型式继承紧密相关的一种思路。寄生式继承的思路与寄生构造函数和工程模式类似,即创建一个仅用于封装继承过程的函数,该函数的内部以某种方式来增强对象,最后再像真的是它做了所有工作一样返回对象。下面的代码示范了寄生式继承的模式
function object(o){ function F(){} F.prototype = o; return new F(); } function createAnother(original){ var clone = object(original);//通过调用函数创建一个新对象 clone.sayHi = function(){//以某种方式来增强这个对象 console.log('hello') } return clone;//返回这个对象 }
在这个例子中createAnother函数接收了一个参数,也就是将要作为新对象基础的对象。然后,把这个对象传递给object(),将返回的结果赋值给clone,再为clone对象添加一个新的方法sayHi(),最后返回clone对象。可以像下面这样使用createAnother函数:
var person = { name:"Alvin", friends:['Yannis',"Lucy"] } var anotherPerson = createAnother(person); anotherPerson.sayHi();//hello
这个例子中的代码基于person返回了一个新对象-anotherPerson。新对象不仅具有person的所有属性和方法,而且还有自己的sayHi()方法。
在主要考虑对象而不是自定义类型和构造函数的情况下,寄生式继承也是一种有用的模式。前面示范继承模式时使用的object()函数不是必须。任何能够返回新对象的函数都可以。
使用寄生式继承来为对象添加函数,会由于不能做到函数复用而降低效率;这点与构造函数模式类似。
更多相关内容 -
浅谈JS继承_寄生式继承 & 寄生组合式继承
2020-10-21 17:44:47下面小编就为大家带来一篇浅谈JS继承_寄生式继承 & 寄生组合式继承。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 -
JavaScript寄生式组合继承
2021-08-07 17:14:57组合继承(通过改变this指向进行继承) 组合继承也被称为伪经典继承,它综合了我们昨天说的原型链和盗用构造函数,将两者的优点结合在了一起。它的基本思想是使用原型链继承原型上的属性和方法,通过盗用构造函数...组合继承(通过改变this指向进行继承)
组合继承也被称为伪经典继承,它综合了我们昨天说的原型链和盗用构造函数,将两者的优点结合在了一起。它的基本思想是使用原型链继承原型上的属性和方法,通过盗用构造函数继承实例属性,这样的好处就是可以把方法定义在原型上复用,每个实例又有自己的属性。
// 先声明一个构造函数 SuperType ,并且给它定义属性 function SuperType (name) { this.name = name; this.colors = ["red","yellow","bule"]; } // 给构造函数的原型对象上添加方法 sayName SuperType.prototype.sayName = function(){ console.log(this.name) } // 声明一个构造函数 SubType function SubType(name,age){ // 通过 call 方法修改 this 指向,这样SubType 这个构造函数就可以访问到构造函数 SuperType 里面的属性以及原型对象上的属性和方法 SuperType.call(this,name); this.age = age; } // 把刚开始定义的那个构造函数 SuperType 的实例对象赋值称为构造函数 SubType 的原型对象 SubType.prototype = new SuperType(); // 给构造函数 SubType 的原型对象添加 sayAge 方法 SubType.prototype.sayAge = function(){ console.log(this.age); } // 实例化 SubType let instancel = new SubType("jackson",22); //就可以访问自身以及继承下来的属性和方法 instancel.colors.push("pink"); instancel.sayName(); // "jackson" instancel.sayAge();//22 console.log(instancel.colors);// ["red", "yellow", "bule", "pink"] let instance2 = new SubType("bear", 20); console.log(instance2.colors); // ["red", "yellow", "bule"] instance2.sayName(); // "bear"; instance2.sayAge(); // 20
组合继承弥补了原型链和盗用构造函数的不足,是js中使用最多的继承模式。
寄生式继承
寄生式继承就是用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。
// 寄生式继承 function subobject(obj) { let clone = Object(obj); clone.sayName = function(){ console.log("jackson") }; return clone; } let sub = { name:"bear" } let sup = subobject(sub); sup.sayName();//jackson
寄生式继承同样适合主要关注对象,而不在乎类型和构造函数的场景。object()函数不是寄生式继承所必需的,任何返回新对象的函数都可以在这里使用。
寄生式组合继承
组合继承存在这一定的效率问题,它的父类构造函数始终会被调用俩次,一次在创建字类原型时调用,另一次在子类构造函数中调用。本质上子类只需要在执行时重写自己的原型就行了。
function inheritPrototype(subType, superType) { let prototype = Object(superType.prototype); // 创建对象 prototype.constructor = subType; // 增强对象 subType.prototype = prototype; // 赋值对象 }
这个 inheritPrototype()函数实现了寄生式组合继承的核心逻辑。这个函数接收两个参数:子类构造函数和父类构造函数。在这个函数内部,第一步是创建父类原型的一个副本。然后,给返回的 prototype 对象设置 constructor 属性,解决由于重写原型导致默认 constructor 丢失的问题。最后将新创建的对象赋值给子类型的原型。如下例所示,调用 inheritPrototype()就可以实现前面例子中的子类型原型赋值:
// 先声明一个构造函数 SuperType ,并且给它定义属性 function SuperType (name) { this.name = name; this.colors = ["red","yellow","bule"]; } // 给构造函数的原型对象上添加方法 sayName SuperType.prototype.sayName = function(){ console.log(this.name) } // 声明一个构造函数 SubType function SubType(name,age){ // 通过 call 方法修改 this 指向,这样SubType 这个构造函数就可以访问到构造函数 SuperType 里面的属性以及原型对象上的属性和方法 SuperType.call(this,name); this.age = age; } inheritPrototype(SubType, SuperType); SubType.prototype.sayAge = function () { console.log(this.age); };
这里只调用了一次 SuperType 构造函数,避免了 SubType.prototype 上不必要也用不到的属性, 因此可以说这个例子的效率更高。而且原型链仍然保持不变。
寄生式组合继承可以算是引用类型继承的最佳模式。
-
JavaScript继承基础讲解(原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承)
2020-10-25 13:47:48主要介绍了JavaScript继承基础讲解,原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承,需要的朋友可以参考下 -
JavaScript实现继承之寄生式继承
2020-09-21 10:20:37什么是寄生式继承 寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,后再像真的是它做了所有工作一样返回对象。 例如: function ...什么是寄生式继承
寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,后再像真的是它做了所有工作一样返回对象。
例如:function createAnother(original){ var clone = object(original); //通过调用函数创建一个新对象 clone.sayHi = function(){ //以某种方式来增强这个对象 alert("hi"); }; return clone; //返回这个对象 }
在这个例子中,createAnother()函数接收了一个参数,也就是将要作为新对象基础的对象。然后,把这个对象(original)传递给 object()函数,将返回的结果赋值给 clone。再为 clone 对象 添加一个新方法 sayHi(),后返回 clone 对象。可以像下面这样来使用 createAnother()函数:
var person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] }; var anotherPerson = createAnother(person); anotherPerson.sayHi(); //"hi"
-
JavaScript 继承 - - 寄生式组合继承(经典继承)
2021-04-28 14:25:13目录一、回顾 组合继承 (伪经典继承)二、寄生式组合继承 一、回顾 组合继承 (伪经典继承) 结合了构造函数继承+对象原型继承 不足的地方是:每个实例对象 都执行了两次Super函数,一次是prototype赋值,一次...一、回顾 组合继承 (伪经典继承)
-
结合了构造函数继承+对象原型继承
-
不足的地方是:每个实例对象 都执行了两次Super函数,一次是prototype赋值,一次是Super.call
-
并且 我们预期是想继承 父级的原型属性,而Suber.prototype = new Super(); 还另外承了this 对象,
// 组合继承 function Super() { this.pbrand = 'super'; // 添加引用值 this.a = [1, 2, 3, 4, 5]; } function Suber() { this.bbrand = 'suber'; //构造函数继承 Super.call(this); } Suber.prototype = new Super(); //对象原型继承 let suber1 = new Suber(); console.log(suber1);
我曾想那把Suber.prototype = new Super(); , 改成Suber.prototype=Super.prototype;,那不是很奈斯?构造函数继承this,Suber.prototype = Super.prototype;继承prototype。后来经实践发现:
function Super() { this.pbrand = 'super'; // 添加引用值 this.a = [1, 2, 3, 4, 5]; } Super.prototype.b = ['a','b']; function Suber() { this.bbrand = 'suber'; //构造函数继承 Super.call(this); } Suber.prototype = Super.prototype; Suber.prototype.str = 'suber'; let suber1 = new Suber(); console.log(suber1);
结果发现,Suber 与 Super的实例中原型值一样。因为 prototype 也是引用值,经过 Suber.prototype = Super.prototype,两者指向同一块内容。
那有没有完美解决伪经典继承缺陷的方法呢?有,那就是接下来的寄生式组合继承。二、寄生式组合继承
听名字猜它结合了哪些继承方式:寄生式,组合(构造)。
// 经典继承 寄生式组合继承 // 寄生式的核心:工厂函数 function inheritPrototype(sub,sup){ // Object.create是ES5才有的,为了兼容可以自己写一个函数 // 只继承了prototype let prototype = Object.create(sup.prototype); sub.prototype = prototype; // 增强对象:标明构造函数 prototype.constructor = sub; } // 父级 function Super(){ this.brand = 'super'; this.a = ['a','b']; } Super.prototype.say = function(){ console.log('i`m ',this.brand); } // 子级 function Suber (){ this.brand = 'suber'; this.a = [1,2,3,4]; Super.call(this); } //调用工厂函数实现继承 inheritPrototype(Suber,Super); let suber1 = new Suber(); let super1 = new Super(); // 修改一下子级的原型 Suber.prototype.str = 'suber'; console.log(suber1); console.log(super1);
结果可以看出:
- 子级的原型更改,不会影响到父级的原型,
- 父级的原型,子级也能继承
- 父级的this 对象,子级也能继承
- 所以这是经典继承!
要说还有没有别的继承:es6 新引入的class了解一下…
-
-
JS继承-(二)原型式继承、寄生式继承、寄生组合继承
2022-01-19 13:21:36原型式继承 原理等同ES5的Object.create()方法, 创建一个函数,使这个函数成为括号中obj的构造函数,也就是这个函数的原型指向这个obj 然后返回这个构造函数的实例,是一个浅拷贝,新实例的引用数据类型改变会让... -
[js高手之路]原型式继承与寄生式继承详解
2020-10-19 07:27:32下面小编就为大家带来一篇[js高手之路]原型式继承与寄生式继承详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 -
JS面向对象——原型式继承函数、寄生式继承函数、寄生组合式继承
2022-03-08 15:41:02一、原型式继承函数 回顾一下JavaScript想...寄生式继承的思路是结合原型类继承和工厂模式的一种方式; 即创建一个封装继承过程的函数, 该函数在内部以某种方式来增强对象,最后再将这个对象返回; 三、寄生组合式 -
JavaScript 原型式继承 和 寄生式继承
2020-09-09 10:32:54一、原型式继承本质其实就是个浅拷贝,以一个对象为模板复制出新的对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 function object( o ){ var G ... -
JS-寄生组合式继承
2021-12-25 12:26:29js的继承组合式继承-es6之前最佳继承方式 -
JavaScript简餐——关于寄生式继承
2021-10-17 21:49:01文章目录前言一、什么是寄生式继承?二、使用实例三、总结 前言 写本《JavaScript简餐》系列文章的目的是记录在阅读学习《JavaScript高级程序设计(第4版)》一书时出现的各个知识点。虽是对读书的笔记和总结,但是... -
[js高手之路]原型式继承与寄生式继承
2019-11-04 09:08:09一、原型式继承本质其实就是个浅拷贝,以一个对象为模板复制出新的对象 1 function object( o ){ 2 var G = function(){}... -
【JS】JavaScript继承 - 原型链 - 盗用构造函数 - 组合继承 -原型式继承 - 寄生式继承 - 寄生式组合继承
2021-05-24 16:15:09寄生式继承6. 寄生式组合继承参考 继承是面向对象编程中讨论最多的话题。实现继承是ECMAScript唯一支持的继承方式,而这主要是通过原型链实现的。 1. 原型链 复习一下 构造函数、原型对象、实例对象之间的关系 ... -
JavaScript中的继承——寄生继承。
2021-07-10 17:05:37寄生继承相当于对原型继承的二次封装,并在二次继承中对继承的对象进行拓展,使其不仅拥有父类的属性方法也拥有新加的属性方法。 function Person(name, age) { this.name = name; this.age = age; } Person.... -
JavaScript寄生组合式继承实例详解
2020-10-18 20:10:33主要介绍了JavaScript寄生组合式继承,结合实例形式详细分析了寄生组合式继承原理、实现方法与相关注意事项,需要的朋友可以参考下 -
js代码-JS的继承 1、原型继承 2、构造函数的继承 ...5、寄生式继承 6、寄生式组合继承
2021-07-15 00:29:38js代码-JS的继承 1、原型继承 2、构造函数的继承 3、组合继承 4、原型式继承 5、寄生式继承 6、寄生式组合继承 -
JS基础--组合继承,寄生组合式继承
2019-05-13 17:03:29以下内容总结自《JavaScript高级程序设计(第3版)》 一. 组合继承 组合继承使用原型链实现对原型属性和方法的继承,使用借用构造函数实现对实例属性的继承(引用类型的属性写在构造函数里)。 示例: function ... -
JavaScript寄生组合式继承原理与用法分析
2020-10-17 12:56:36主要介绍了JavaScript寄生组合式继承,结合实例形式分析了javascript寄生组合式继承的原理、定义与简单使用方法,需要的朋友可以参考下 -
继承 ---寄生式继承和寄生组合式继承
2019-10-31 09:23:55寄生式继承 function obj(o){ function F(){} F.prototype=o; return new F(); } function createPerson(orig){ ... -
js代码-寄生式继承demo
2021-07-16 16:20:03js代码-寄生式继承demo -
【JavaScript源代码】简单谈谈JavaScript寄生式组合继承.docx
2021-12-30 14:18:58简单谈谈JavaScript寄生式组合继承 组合继承也被称为伪经典继承,它综合了我们昨天说的原型链和盗用构造函数,将俩者的有点结合在了一起。它的基本思想是使用原型链继承原型上的属性和方法,通过盗用构造函数继承... -
寄生组合式继承的实现?
2022-01-22 19:56:31在上篇博客中总结了六种继承方式,这里我们主要说一下寄生组合式继承的实现。 寄生组合式继承方式是目前使用最为广泛的一种继承方式。 function Person(name, age) { this.name = name this.age = age } Person.... -
[js高手之路]寄生组合式继承的优势详解
2020-12-09 17:20:36在之前javascript面向对象系列的文章里面,我们已经探讨了组合继承和寄生继承,回顾下组合继承: function Person( uName ){ this.skills = [ 'php', 'javascript' ]; this.userName = uName; } Person.... -
JS寄生组合继承
2022-02-27 11:11:57寄生组合继承 就是 组合继承 + 原型继承 的结合体 js内部会把这个寄生组成封装成 extend function Father(name) { this.name = name this.hbody = ['吃饭', '睡觉', '打豆豆'] } Father.prototype.getName = ...