-
2021-07-10 17:05:37
寄生继承
寄生继承相当于对原型继承的二次封装,并在二次继承中对继承的对象进行拓展,使其不仅拥有父类的属性方法也拥有新加的属性方法。
function Person(name, age) { this.name = name; this.age = age; } Person.prototype = { sleep: function () { console.log(this.name + "在睡觉!"); } } //实例继承 function Student(obj) { function fun() { } //寄生到 fun函数的prototype上面 fun.prototype = obj; return new fun(); } var p = new Person('小明',18);//实例化person //带个壳子 function getObj() { var stu=Student(p); stu.work="学习"; return stu; } var s = getObj(); console.log(s); s.sleep();
用寄生式继承来为对象添加函数,会由于不能做到函数复用而降低效率。
更多相关内容 -
寄生继承
2019-08-08 16:01:16这个和前两种继承方式又有什么不同呢? 需要仔细体会 function Vehicle() { this.engines = 1; } Vehicle.prototype.igintion = function() { console.log("Turning on my engine."); }; Vehicle.prototype....这个和前两种继承方式又有什么不同呢?
需要仔细体会function Vehicle() { this.engines = 1; } Vehicle.prototype.igintion = function() { console.log("Turning on my engine."); }; Vehicle.prototype.drive = function() { this.igintion(); console.log("Steering and moving forward!"); }; function Car() { var car = new Vehicle(); car.wheels = 4; var vehDrive = car.drive; car.drive = function() { vehDrive.call(this); console.log("Rolling on " + this.wheels + " wheels!"); }; return car; } var myCar = new Car(); Object.toString(); Object.prototype.toString(); myCar.drive();
-
js组合继承和组合寄生继承
2021-03-03 17:00:13js组合继承和组合寄生继承 js设计之初是没有继承的概念的,如果要实现ES6中class A extends B的形式,需要借用prototype和Function.prototype.apply()方法或Function.prototype.call()方法。 原型链继承方式:B....js组合继承和组合寄生继承
js设计之初是没有继承的概念的,如果要实现ES6中
class A extends B
的形式,需要借用prototype
和Function.prototype.apply()
方法或Function.prototype.call()
方法。- 原型链继承方式:
B.prototype = A.prototype;
,目的是继承父类方法 - 构造函数继承方式:
A.apply(this, arguments)
,目的是继承父类成员变量
我们先看两个类
// 父类 var A = function(name){ this.name = name;// 父类属性 } // 父类方法 A.prototype.setName = function(name){ this.name = name } // 子类 var B = function (){ A.apply(this, arguments);// 继承属性 } // 子类方法 B.prototype.getName = function(){ return this.name; }
我们的目的是实现子类A继承父类B的属性
name
和方法setName()
,并且B自有的属性和方法不能丢失1.组合继承
将原型链继承和构造函数继承两种方式结合,
apply()
方法改变父类的this指向,prototype
继承父类成员方法// 父类 var A = function (name) { this.name = name; } A.prototype.setName = function (name) { this.name = name; } // 子类 var B = function () { A.apply(this, arguments);// 将A的this指向B的this, 并且A接收B的构造函数参数 } B.prototype = A.prototype;// 继承父类方法 B.prototype.constructor = B;// 子类构造函数被覆盖掉了,恢复回来 // 必须先写上面两行,才能给子类添加成员方法 B.prototype.getName = function () { return this.name; } // 测试 var b = new B('张三') b.setName('老刘') console.log('name=', b.getName())
优缺点分析
优点:
- 写法简单,可满足基本使用
缺点:
- 1.顺序不能错。只能现将子类
prototype
执行父类的prototype
,在增加子类原型方法。一旦顺序反了就会丢失子类自己的方法 - 2.原型链上
__proto__
看不到父类,实际上只是把父类的属性和方法指向了子类,并不是真正的继承
2.组合继承 + 寄生继承
- 1.我们可以创建一个内部函数作为寄生母体
var fun = function(){}
, - 2.让这个母体继承父类的原型
fun.prototype = A.prototype
, - 3.再把寄生母体的
contructor
指向子类,fun.prototype.contructor = B
- 4.创建寄生对象
var obj = new fun()
,这个obj
没有任何属性,可以认为是个空对象,此时它的__proto__
已经指向了A
- 5.把子类B的原型链替换为上面常见的寄生对象
obj
,B.prototype = obj
- 6.寄生继承完成,结束
// 父类 var A = function(name){ this.name = name;// 父类属性 } // 父类方法 A.prototype.setName = function(name){ this.name = name } // 调用此方法进行继承 var _extends = function(sub, sup){ // 寄生函数 var fun = function(){ } fun.prototype = sup.prototype;// 原型链继承 fun.prototype.contructor = sub;// contructor丢失,恢复 sub.prototype = new fun();// 寄生函数创建的实例,里面只有原型链(__proto__) } // 子类 var B = function (){ A.apply(this, arguments);// 继承属性 } _extends(B, A); // 子类方法 B.prototype.getName = function(){ return this.name; } var b = new B('张三') b.setName('李思') console.log(b.getName())
优缺点分析
优点:
- 1.解决掉
组合继承
不是真正继承的毛病 - 2.继承后的原型链比较清晰易懂
缺点:
- 额外增加一个寄生函数,占用更多内存
参考资料
- 原型链继承方式:
-
类的继承-ES5寄生继承与组合继承以及ES6继承方法
2022-03-01 10:22:01ES5寄生继承、组合继承、常见问题、ES6继承ES5没有类,所以函数即是类,习惯类的首字母大写
基本类型:object、function、array、boolean、number、string(记忆:即6个基本数据类型,用function和array替换掉null、undefined)
明确一点:ES5,1、实例(new)可以继承父类原型方法以及父类私有属性。
2、寄生继承只做继承父类原型方法,不继承父类私有属性;
3、组合继承即继承父类原型方法和继承父类私有属性。
ES5继承从两方面讲:继承父类私有属性,继承父类原型方法
最终目的:创建实例A继承Student.prototype继承People.prototype,实例A继承学生类,学生类继承人类。即:A -> Student.prototype -> People.prototype
//父类(人类):
function People(name){ this.name = name; //构造函数,提供私有属性 }
People.prototype.SayName = function (){ console.log(this.name); }
//子类(学生类):
function Student(){ this.number = number; //构造函数,提供私有属性 }一、目的:继承父类原型方法
错误做法:
有些人的做法是:Student.prototype = new People()
这样子做不会报错,也确实能够继承到父类的原型(方法)。但仔细一看,有他的“尴尬之处”。
不好的点有:1、我只想Student子类继承People父类的原型(方法),但这么实例的话使得Student.prototype(学生原型链)变成People父类的一个实例了(父类的原型方法以及私有属性,变成了Student.prototype的公有属性,多继承了一个东西,即父类的私有属性);
2、这样子做,使得People类“无缘无故”调用了一次(影响性能);
正确做法(寄生继承):
将Student.prototype = new People()换成以下写法
function fn(){
let fun = function(){};
fun.prototype=People.prototype; //将People.prototype赋值给fun.prototype
return new fun()
}
Student.prototype = fn();//这样子继承,fun是一个没有私有属性,只有人类的原型方法,是一个很干净的函数。即:达到了我们的目的,只继承父类的原型方法。
二、目的:继承父类私有属性
在学生类创建时进行
function Student(name,number){
People.call(this,name); //达成目的,继承父类私有属性
this.number = number;
}
最后将目的一、目的二整合就成了组合继承
//父类(人类):
function People(name){ this.name = name; }
People.prototype.sayName = function (){ console.log(this.name); }
//子类(学生类):
function Student(name,number){
People.call(this,name); //达成目的,继承父类私有属性
this.number = number;
}
function fn(){
let fun = function(){};
fun.prototype=People.prototype; //将People.prototype赋值给fun.prototype
return new fun()
}
Student.prototype = fn();
Student.prototype.sayNumber = function(){console.log(console.log(this.number))}//给Student原型添加方法,根据自己的需求决定是否添加。
实例化:let A = new Student()
这样子A实例就可访问sayName和sayNumber原型方法了。达到我们的最终目的。即:A -> Student.prototype -> People.prototype
如果ES5的继承你已经能够清楚,那么ES6的继承学习起来将很轻松
ES6有类的概念,即class,不再用function创建类
创建父类:class People{
constructor(name){ this.name = name; }//构造函数,提供私有属性(constructor)
sayName(){console.log(this.name)}//原型方法,不再用prototype添加
}
ES6继承:创建子类继承子类:
class Student extends People{ //extends就相当于继承了父类的原型方法
constructor(name,number){
super(name); this.number = number;
//super继承父类私有属性,相当于ES5中People.call(this,name);
}
}
实例化:let oA = new Student('天才威',24)
Tip1:可以只写extends不写constructor,相当于没有私有属性。
Tip2:写了constructor,就必须写super,且需要写在自己的私有属性之前。否则报错
篇幅过长,如有所遗漏评论区友好交流!
-
JS继承之寄生继承
2018-09-05 16:58:57JavaScript继承还有一种继承模式——寄生继承。 举个例子: function object(o) { function F() {}; F.prototype = o; return new F(); } var twoD = { name: '2D shape', dimensions: 2 } function triangle... -
JS中的六种继承:原型链、盗用构造函数、组合继承、原型式继承、寄生继承、组合寄生继承
2021-11-10 22:18:26继承本质上就是一个对象复用另一个对象的属性和方法,注意,属性和方法的复用效果是不同的,从这点出发去理解继承,也就能理解为什么会产生六种继承。 -
举例说明class继承与组合寄生继承的差别
2020-09-10 22:36:16class -
组合寄生继承和class继承的区别
2020-03-19 00:42:42先看下什么是原型继承 function object( o ){ var F = function(){}; F.prototype = o; return new F(); } var obj = { name : 'li', ... -
深入理解组合继承和寄生继承
2019-05-08 21:46:56从简单的层面深刻理解组合继承和寄生继承方式的由来 关于组合继承和寄生继承的文章已经很多了,但是多半都是将如何实现组合继承和组合继承的缺点,寄生继承的缺点的。 最近看到这篇文章,觉得很不错,思路清晰的,... -
js实现继承的6种方式 寄生继承没弄懂
2016-05-10 21:17:15js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明确的继承机制,而是通过模仿实现的,根据js语言的本身的特性,js实现继承有以下通用的几种方式 1.使用对象冒充实现继承(该种实现方式可以实现多继承) ... -
JavaScript 中原型继承与寄生继承
2020-06-16 07:47:10引言 在 ES5 中,继承的方式...如果是的话,那究竟是为什么要选择寄生继承呢?请往下看: 继承方式 1. 原型组合继承 function Father(){ this.msg = "Hello" } Father.prototype.say = function(){console.log(this.ms -
javascript学习笔记--经典继承、组合继承、原型式继承、寄生继承以及寄生组合继承...
2018-06-10 15:36:00经典继承 js中实现经典继承的方式是通过构造函数来实现的,即在子类中对父类调用call方法。 function Geometric() { this.time = ""; this.color = ""; this.base = function () { ... -
<JavaScript> 寄生继承详解
2019-09-26 23:58:55// 将原型继承和非原型继承组合为一体的继承方式叫做组合继承,但是这种方法的继承是有一点小缺陷的,下级函数继承了无用的属性,所以我们有了寄生继承来解决污染问题; //创建上级构造函数-食物 function Food... -
寄生继承第二次理解
2021-02-19 23:59:52不论再有孙类还是爷类,都是像这样子类复制父类的原型作为自己这个类的新的原型,这样就做到了继承了父类的原型方法和属性,如果有很多个类一直继承下去,那么就会是这样的情况,他们每个都是单独的,没有说谁连线上谁 ... -
原型链继承/借用构造函数继承/组合式继承/寄生继承/es6类继承
2021-12-27 14:00:07继承 子类能够使用父类的属性和方法 原型链继承 创建人的类 function Person(name, age) { this.name = name this.age = age } Person.prototype.say = function () { console.log('说话了') } const p1 = ... -
js组合继承与寄生继承
2018-10-30 17:57:00/* 组合继承*/function Parent(){ this.name='wsq'; this.sex='nan'; this.sleep=function(){ alert("success"); }};Parent,prototype.eat=function(){ alert("yes");}; function Clild(name){ Parent.call(this);... -
浅谈JS继承_寄生式继承 & 寄生组合式继承
2020-10-21 17:44:47下面小编就为大家带来一篇浅谈JS继承_寄生式继承 & 寄生组合式继承。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 -
JS寄生组合继承
2022-02-27 11:11:57寄生组合继承 就是 组合继承 + 原型继承 的结合体 js内部会把这个寄生组成封装成 extend function Father(name) { this.name = name this.hbody = ['吃饭', '睡觉', '打豆豆'] } Father.prototype.getName = ... -
javascript 的七种继承方式(五)寄生式继承
2020-08-20 17:14:49寄生式继承是与原型式继承紧密相关的一种思路。寄生式继承的思路与寄生构造函数和工程模式类似,即创建一个仅用于封装继承过程的函数,该函数的内部以某种方式来增强对象,最后再像真的是它做了所有工作一样返回对象... -
JavaScript简餐——寄生组合继承
2021-10-23 22:28:58文章目录前言一、什么是寄生组合继承?二、寄生组合继承的基本模式三、总结 前言 写本《JavaScript简餐》系列文章的目的是记录在阅读学习《JavaScript高级程序设计(第4版)》一书时出现的各个知识点。虽是对读书的... -
继承方式五:寄生式继承
2020-04-22 17:42:11寄生式(parasitic)继承是与原型式继承紧密相关的一种思路,并且同样也是由克罗克夫德推而广之的。寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来... -
继承 ---寄生式继承和寄生组合式继承
2019-10-31 09:23:55寄生式继承 function obj(o){ function F(){} F.prototype=o; return new F(); } function createPerson(orig){ ... -
组合继承和寄生式组合继承
2020-11-18 11:42:02组合继承(伪经典继承) 组合继承综合了原型链和盗用构造函数,...不通过调用父类构造函数给子类原型对象赋值的方式建立继承关系,而是通过寄生式继承继承父类原型,然后将返回的实例对象赋值给子类原型 寄生式组合继承 -
原型式继承和寄生式继承
2019-04-18 19:56:31原型式继承和寄生式继承 -
JS-寄生组合式继承
2021-12-25 12:26:29js的继承组合式继承-es6之前最佳继承方式 -
JavaScript继承基础讲解(原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承)
2020-10-25 13:47:48主要介绍了JavaScript继承基础讲解,原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承,需要的朋友可以参考下 -
JavaScript 继承 - - 寄生式组合继承(经典继承)
2021-04-28 14:25:13目录一、回顾 组合继承 (伪经典继承)二、寄生式组合继承 一、回顾 组合继承 (伪经典继承) 结合了构造函数继承+对象原型继承 不足的地方是:每个实例对象 都执行了两次Super函数,一次是prototype赋值,一次... -
组合继承和寄生组合继承的一点点差别
2021-02-20 17:15:26这里着重记录一下组合继承和寄生继承的区别 组合继承 function Person(name) { this.name = name, this.age = '23' } Person.prototype.sayName = function(){ console.log('my name is'+this.name+'.'); } ... -
JavaScript简餐——关于寄生式继承
2021-10-17 21:49:01文章目录前言一、什么是寄生式继承?二、使用实例三、总结 前言 写本《JavaScript简餐》系列文章的目的是记录在阅读学习《JavaScript高级程序设计(第4版)》一书时出现的各个知识点。虽是对读书的笔记和总结,但是...