JavaScript之原型式继承&寄生式继承和寄生组合式继承以及优缺点

一.原型式继承

1.这种方法并没有使用严格意义上的构造函数,借助原型可以基于已有的对象创建新的对象

function object(o) {
  function F() {}
  F.prototype = o;
  return new F();
}
// 在object()函数内部,先创建一个临时性的构造函数,然后将传入的对象作为这个构造函数原型,最后返回了这个临时类型的一个新实例.
// object()本质上对其中传入的对象进行了一次浅复制
// 看如下的例子:
var person = {
  name: "kebi",
  friends: ["kuli", "hadeng"]
};
var onePerson = object(person);
onePerson.name = "heyushuo";
onePerson.friends.push("heyushuo");
var twoPerson = object(person);
twoPerson.name = "yaoming";
twoPerson.friends.push("yaoming");

//这里打印
console.log(twoPerson); //['kuli','hadeng','heyushuo','yaoming']

缺点: 包含引用类型的属性值始终都会共享相应的值,和原型链继承一样。

2.ES5 通过新增 Object.create()方法规范化了原型式继承,此方法可以接受两个参数,第一个参数最为新对象原型的对象 和一个为新对象定义额外属性的对象.

var person = {
  name: "kebi",
  friends: ["kuli", "hadeng"]
};
var onePerson = Object.create(person, {
  name: "heyushuo"
});
onePerson.friends.push("heyushuo");
var twoPerson = Object.create(person, {
  name: "yaoming"
});
twoPerson.friends.push("yaoming");
//这里打印
console.log(twoPerson); //['kuli','hadeng','heyushuo','yaoming']
// 主:在没有必要创建构造函数,而是指向让一个对象与另外一个对象保持类似的情况下,原型式继承完全可以胜任

二.寄生式继承

创建一个仅用于封装继承过程的函数,该函数在内部以某种形式来做增强对象,最后返回对象。

function createAnother(original) {
  var clone = object(original); // 通过调用 object() 函数创建一个新对象
  clone.sayHi = function() {
    // 以某种方式来增强对象
    console.log("hi");
  };
  return clone; // 返回这个对象
}
// 函数的主要作用是为构造函数新增属性和方法,以增强函数
var person = {
  name: "Nicholas",
  friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi(); //"hi"```

缺点:

  1. 原型继承存在的缺点他都存在
  2. 使用寄生式继承为对象添加方法,会由于不能做到方法的复用而降低效率,这一点和构造函数模式类似

三.寄生组合式继承

寄生组合式继承, 即通过借用构造函数来继承属性, 在原型上添加共用的方法, 通过寄生式实现继承.

//寄生式继承的基本模式
function inheritPrototype(subType, superType) {
  var prototype = Object.create(superType.prototype); // 创建对象,创建父类原型的一个副本
  prototype.constructor = subType; // 增强对象,弥补因重写原型而失去的默认的constructor 属性
  subType.prototype = prototype; // 指定对象,将新创建的对象赋值给子类的原型
}

// 父类初始化实例属性和原型的属性和方法
function SuperType(name) {
  this.name = name;
  this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function() {
  console.log(this.name);
};

// 借用构造函数继承构造函数的实例的属性(解决引用类型共享的问题)
function SubType(name, age) {
  SuperType.call(this, name);
  this.age = age;
}

// 将子类型的原型重写替换成父类的原型
inheritPrototype(SubType, SuperType);

// 对子类添加自己的方法
SubType.prototype.sayAge = function() {
  console.log(this.age);
};

var instance1 = new SubType("heyushuo");
var instance2 = new SubType("kebi");
instance1.sayName(); //heyushuo
instance2.sayName(); //kebi
instance1.colors.push("yellow"); // ["red", "blue", "green", "yellow"]
instance1.colors.push("black"); // ["red", "blue", "green", "black"]

总结:

上边的例子高效的体现了只调用了一次 SuperType 构造函数,并且因此也避免了在 SubType.prototype 上面创建不必要的 多余的属性.与此同时,原型链还能保持不变

原文地址:https://www.cnblogs.com/heyushuo/p/10057676.html

时间: 2024-08-23 14:59:05

JavaScript之原型式继承&寄生式继承和寄生组合式继承以及优缺点的相关文章

JavaScript继承基础讲解,原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承

说好的讲解JavaScript继承,可是迟迟到现在讲解.废话不多说,直接进入正题. 既然你想了解继承,证明你对JavaScript面向对象已经有一定的了解,如还有什么不理解的可以参考<面向对象JS基础讲解,工厂模式.构造函数模式.原型模式.混合模式.动态原型模式>,接下来讲一般通过那些方法完成JavaScript的继承. 原型链 JavaScript中实现继承最简单的方式就是使用原型链,将子类型的原型指向父类型的实例即可,即“子类型.prototype = new 父类型();”,实现方法如下

JavaScript之面向对象学九(原型式继承和寄生式继承)

一.原型式继承 该继承模式是由道格拉斯*克罗克福德在2006年提出的实现继承的方法. 模式的基本思路:借助原型可以基于已有的对象创建新的对象,同时还不必因此创建自定义类型. 代码如下: function object(o) { function F() { //定义一个F类型的对象 this.name="111"; } F.prototype=o;//使F的原型对象指向传入对象,也就是说F继承了传入的对象,也相当于用传入的对象重写了F的原型对象 相当于如下代码 /* F.prototy

[js高手之路]原型式继承与寄生式继承

一.原型式继承本质其实就是个浅拷贝,以一个对象为模板复制出新的对象 1 function object( o ){ 2 var G = function(){}; 3 G.prototype = o; 4 return new G(); 5 } 6 var obj = { 7 name : 'ghostwu', 8 age : 22, 9 show : function(){ 10 return this.name + ',' + this.age; 11 } 12 }; 13 var obj2

javascript中类式继承和原型式继承的实现方法和区别

在所有面向对象的编程中,继承是一个重要的话题.一般说来,在设计类的时候,我们希望能减少重复性的代码,并且尽量弱化对象间的耦合(让一个类继承另一个类可能会导致二者产生强耦合).关于“解耦”是程序设计中另一个重要的话题,本篇重点来看看在javascript如何实现继承. 其它的面向对象程序设计语言都是通过关键字来解决继承的问题(比如extend或inherit等方式).但是javascript中并没有定义这种实现的机制,如果一个类需要继承另一个类,这个继承过程需要程序员自己通过编码来实现. 一.类式

组合继承 和 原型式继承、寄生组合式继承

//以下代码均摘自 Nicholas C.Zakas<Professional JavaScript for Web Developers> //组合继承实例代码: function SuperType(name) {     this.name = name;     this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function() 

JavaScript中的继承之寄生式继承

寄生式(parasitic)继承是与原型式继承紧密相关的一种思路. 寄生式继承的思路与寄生构造函数和工厂模式类似(这里提到的寄生构造函数和工厂模式都是创建对象的方法,有时间会写博客),即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象.最后再像真的是它做了所有工作一样返回对象. 还是要用之前的object函数: function object(o){ function F(){} F.prototype = o; return new F(); } 以下代码示范了寄生式继承.

JavaScript ----------------- 寄生式继承

寄生式继承 寄生式继承是于原型式继承紧密相关的一种思路.寄生式基础的思路与寄生构造函数和工厂模式类似,既创建一个仅用于封装继承过程的函数,该函数内部以某种方式来增强对象,最后再像真地是它做了所有工作一样返回对象. 以下代码示范了寄生式继承模式. function object(o){  function F(){ } F.prototype=o;  return new F(); }; function createAnother(original){ var clone = object(or

javascript原型式继承

之前的文章里有提到过javascript类式继承,那种继承方式极大的方便了其他语言(非javascript)程序员使用javascript来实现继承,但是有缺点,就是建立了一个非必要的构造函数,那这篇文章我们来谈一谈具有javascript自身特色的原型式继承. 我们先来看一看下面的代码: var Car = { color: 'red', size: 'big', getAttr: function() { return this.color } } var car1 = Object.cre

JS 继承(类式 与 原型式)

1. /* -- 类式继承 -- *///先声明一个超类 function Person(name) { this.name = name;}//给这个超类的原型对象上添加方法 getName Person.prototype.getName = function() { return this.name;}//实例化这个超var a = new Person('Darren1')console.log(a.getName());//Darren1 //再声明类 function Program