Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
heyushuo opened this issue Dec 27, 2019 · 0 comments

Comments

@heyushuo
Copy link
Owner

一.原型式继承

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 上面创建不必要的 多余的属性.与此同时,原型链还能保持不变

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant