// 原型继承
function Parent(name){
    this.type = 'Parent'
    this.name =  name || 'Parent'
    this.attr = {
        attr1: 1
    }
}
Parent.prototype.say = function(){console.log(this.type)}
function Child(){
    this.type = 'Child'
}
Child.prototype = new Parent()
var c = new Child()
var c1 = new Child()
// 缺点:1、公用父类属性,单实例修改后影响所有子实例;2、子类实例化时无法给父类传参
c.attr.attr1=2
c1.attr.attr1 // 2
// 构造函数继承
function Parent(name){
    this.type = 'Parent'
    this.name =  name || 'Parent'
    this.attr = {
        attr1: 1
    }
}
Parent.prototype.say = function(){console.log(this.type)}
function Child(name){
    Parent.call(this,name)
    this.type = 'Child'
}
var c = new Child()
var c1 = new Child()
// 缺点:1、无法继承父类原型上的属性与方法;2、无法复用父类方法
c.say()  //Uncaught TypeError: c.say is not a function
// 寄生组合继承,ES6的 class 语法也是使用的此种方式
function Parent(name){
    this.type = 'Parent'
    this.name =  name || 'Parent'
    this.attr = {
        attr1: 1
    }
}
Parent.prototype.say = function(){console.log(this.type)}
function Child(name){
    // 提现构造函数继承
    Parent.call(this, ...agruments)
    this.type = 'Child'
}
// 如下提现原型继承
Child.prototype =  Object.create(Parent.prototype) // 原型寄生在新创建的对象;
Child.prototype.constructor = Child
var c = new Child('c')
var c1 = new Child('c1')
c.say()  
// Object.create 过程
function createFunc(){
    function Fn(){}
    Fn.prototype = arguments[0]
    Fn.prototype.constructor = arguments[0]
    var re = new Fn()
    if(arguments[0] === null){
        re.__proto__  = null
    }
    Object.defineProperties(re, arguments[1])
    return re
}
// new Object() 过程
- 创建一个空的简单JavaScript对象(即{});
- 链接该对象(即设置该对象的构造函数)到另一个对象 ;
- 将步骤1新创建的对象作为this的上下文 ;
- 如果该函数没有返回对象,则返回this。
- new会创建一个新对象,并且这个新对象继承构造函数的prototype,也就是说创建的实例的proto指向构造函数的prototype
 new Object()会创建一个实例,该实例的proto指向Object的prototype