最完整的继承方式

58 阅读2分钟

1、原型链继承

// 缺点
// 1、S(子级)不能向P(父级)传参数
// 2、共享的属性可被更改
function P(name) {
    this.name = name
}
P.prototype.sayName = function() {
    console.log(this.name)
}
function S() {}
S.prototype = new P('test');
let children = new S();

2、构造函数继承

// 优点
// 1、可以在S向P传参数
// 2、避免了引用类型的属性被共享
// 缺点
// 1、每次新建实例都需要new
function P(name) {
    this.names = [];
    this.pushName = function() {
        this.names.push(name);
    }
}
function S(name) {
    P.call(this, name);
}
let children = new S('test');

3、组合继承(原型链继承和构造函数继承)

// 缺点
// 1、我们打印一下child1发现,创建的实例和原型上(__proto__)存在两份相同的属性。造成了资源浪费和占用
function P(name) {
  this.name = name;
}

P3.prototype.getName = function () {
  console.log(this.name);
};

function S(name, age) {
  P.call(this, name);
  this.age = age;
}

S.prototype = new P('张三');
let children = new S('李四', 20);

4、原型式继承

// Object.create会将当前属性和原型属性分开
function createObj(o) {
  function F() {}
  F.prototype = o;
  return new F();
}

let person = {
  name: 'wq',
  friends: ['ww'],
};

let person1 = createObj(person);

5、寄生式继承

// 缺点:跟构造函数模式一样,每次创建对象都会创建一遍方法
function personNew(o) {
  var clone = Object.create(o);
  clone.sayName = function () {
    console.log('clone');
  };
  return clone;
}

let person = {
  name: 'wq',
  friends: ['ww'],
};

let person2 = personNew(person);
  • 原型式继承本质其实就是个浅拷贝,以一个对象为模板复制出新的对象;
  • 寄生式继承就是把原型式继承再次封装,然后在对象上扩展新的方法,再把新对象返回; 6、寄生组合式继承
function Parent (name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child (name, age) {
    Parent.call(this, name);
    this.age = age;
}
// 组合继承方法
// Child.prototype = new Parent();
// 寄生组合继承方法
var F = function () {};
F.prototype = Parent.prototype;
Child.prototype = new F();

var child1 = new Child('小鱼', '18');
console.log(child1)

7、最终继承封装

function P(name) {
    this.name = name
    this.colors = ['red']
}

P.prototype.getName = function(){
    console.log(this.name)
}

function S(name, age) {
    P.call(this, name)
    this.age = age
}

function createObj(o) {
    // Object.create(null) 下面代码是Object.create的填充代码(实现)
    function F() {}
    F.prototype = o
    return new F()
}

function inheritPrototype(S, P) {
    var p = createObj(P.prototype)
    // Object.create()
    // S.prototype = Object.create(S.prototype)
    p.constructor = S
    S.prototype = p
}

inheritPrototype(S, P)
var child1 = new S('wq', 23)
console.log(child1)