编辑代码

// 1. 原型链继承:
// 缺点: 引用值共享问题; 不能传参
// Parent.prototype.grand = 'grand';

// function Parent (name) {
//     this.name = name || 'parent';
//     this.color = ['red', 'orange', 'yellow'];
// }

// function Child () {
// }

// Child.prototype = new Parent();
// var child1 = new Child('child1');
// var child2 = new Child('child2');
// console.log(child1.color, 'child1.color')
// console.log(child2.color, 'child2.color')
// console.log(child1.name, 'child1.name')
// console.log(child2.name, 'child2.name')
// console.log(child1.grand, 'child1.grand')
// console.log(child2.grand, 'child2.grand')
// child1.color.push('blue')
// console.log(child1.color, 'child1.color')
// console.log(child2.color, 'child2.color')
// child1.grand = 'ar';
// console.log(child1.grand, 'child1.grand')
// console.log(child2.grand, 'child2.grand')

// 2. 借用构造函数
// 优点:解决了引用值共享的问题;可以通过Child向Parent传参
// 缺点:多执行一次call函数;Parent上的原型不能被继承
// Parent.prototype.grand = 'grand';

// function Parent (name) {
//     this.name = name || 'parent';
//     this.color = ['red', 'orange', 'yellow'];
// }

// function Child (name,) {
//     Parent.call(this, name);
// }

// var child1 = new Child('child1');
// var child2 = new Child('child2');
// console.log(child1.color, 'child1.color')
// console.log(child2.color, 'child2.color')
// console.log(child1.name, 'child1.name')
// console.log(child2.name, 'child2.name')
// console.log(child1.grand, 'child1.grand')
// console.log(child2.grand, 'child2.grand')
// child1.color.push('blue')
// console.log(child1.color, 'child1.color')
// console.log(child2.color, 'child2.color')

// 3. 组合继承:将原型链继承和借用构造函数阶乘结合在一起
// 优点:.Parent上的原型可以被继承;解决了引用值共享的问题;可以通过Child向Parent传参
// 缺点:函数多执行了一次call
// Parent.prototype.grand = 'grand';

// function Parent(name) {
//     this.name = name || 'parent';
//     this.color = ['red', 'orange', 'yellow'];
// }

// function Child(name, age) {
//     Parent.call(this, name);
//     this.age = age;
// }

// Child.prototype = new Parent();
// Child.prototype.constructor = Child;

// var child1 = new Child('child1', 18);
// var child2 = new Child('child2', 19);
// console.log(child1.age, 'child1.age')
// console.log(child2.age, 'child2.age')
// console.log(child1.color, 'child1.color')
// console.log(child2.color, 'child2.color')
// console.log(child1.name, 'child1.name')
// console.log(child2.name, 'child2.name')
// console.log(child1.grand, 'child1.grand')
// console.log(child2.grand, 'child2.grand')
// child1.color.push('blue')
// console.log(child1.color, 'child1.color')
// console.log(child2.color, 'child2.color')

// 4. 原型式继承: 用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理
// 缺点: 所有实例都会继承原型上的属性;无法实现复用
// var car = {
//     name : 'car',
//     color : ['red', 'orange', 'yellow']
// }

// function object (o) {
//     function F () {};
//     F.prototype = o;
//     return new F();
// }

// var car1 = object(car);
// var car2 = object(car);
// console.log(car1.color, 'car1.color')
// console.log(car2.color, 'car2.color')
// console.log(car1.name, 'car1.name')
// console.log(car2.name, 'car2.name')
// car1.color.push('blue')
// console.log(car1.color, 'car1.color')
// console.log(car2.color, 'car2.color')

// 5.寄生式继承
// 优点:没有创建自定义类型
// 缺点:没用到原型,无法复用
// function createObject (o) {
//     var clone = Object.create(o);
//     clone.sayHi = function () {
//         console.log('hi');
//     }
//     return clone;
// }

// var car = {
//     name : 'car',
//     color : ['red', 'orange', 'yellow']
// }

// var car1 = createObject(car);
// console.log(car1.name, 'car1.name');
// console.log(car1.color, 'car1.color');
// console.log(car1.sayHi, 'car1.sayHi');
// car1.sayHi();

// 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;
}

// 关键的三步
var F = function () {};

F.prototype = Parent.prototype;

Child.prototype = new F();

var child1 = new Child('kevin', '18');

console.log(child1);

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

function prototype(child, parent) {
    var prototype = object(parent.prototype);
    prototype.constructor = child;
    child.prototype = prototype;
}

// 当我们使用的时候:prototype(Child, Parent);