1、我们创建的每一个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
2、原型对象实际就是一个构造函数的实例对象,与普通的实例对象没有什么本质上的区别,js中每一个对象都有一个原型对象。
    不过他比较特殊,该对象所包含的所有属性和方法能够供构造函数的所有实例共享,这就是其他语言所说的继承,而javascript通过原型对象来实现继承,简称原型继承。
    静态原型继承:Object.prototype.[methodfield] ;
3、isPrototypeOf(实例对象)判断原型的方法
4、ECMA5:Object.getPrototypeOf():根据实例对象获得原型对象
5、object.hasOwnProperty(attribute)判断属性是否属于对象本身
6、in 操作符判断对象中是否存在该属性(无论是实例对象还是原型对象)
7、ECMA5新特性Object.keys();拿到当前对象里的所有keys 返回一个数组ECMA5新特性 Object.getOwnPropertyNames 枚举对象所有的属性 :不管该内部属性能否被枚举

 <script type="text/javascript">
     function Person(name,age){
       this.name=name
       this.age=age
     }
     //函数的原型对象
     var obj=Person.prototype
     console.log(obj.constructor)
     
     obj.eating=function(){
       console.log('eating...')
     }
     obj.singing=function  () {
       console.log('singing...')
     }
     
     var p1=new Person('z3',23)
     var p2=new Person('li4',20)
     
     p1.eating()
     p2.singing()

      //Object.getPrototypeOf(实例对象) 获取原型对象
      console.log(Object.getPrototypeOf(p1)==Person.prototype)
      
   </script>
#简单原型
  function Person(){}
  Person.prototype={
   constructor:Person,
   name:'z3',
   age:20,
   eating:function(){console.log('eating...')}
  }
  
  //参数1:重设构造器的对象、参数2:设置什么属性、参数3:Option参数
  Object.defineProperty(Person.prototype,'constructor',{
   enumerable:false,
   value:Person
  })
  
  var p1=new Person()
  
  console.log(Person.prototype.constructor)
  
  //枚举对象的keys
  for(i in p1){
   console.log(i)
  }
  
  </script>
# 常用开发模式
  <script type="text/javascript">
  
  //开发使用模式:组合使用原型对象和构造函数
  function Person(name,age){
   this.name=name
   this.age=age
  }
  Person.prototype={
   constructor:Person,
   sayName:function(){console.log('my name is :'+this.name+"; i am "+this.age)}
  }
  
  var p1=new Person('li4',20)
  var p2=new Person('w5' ,24)
  p1.sayName()
  p2.sayName()
  
  </script>
#原型继承:继承父类的模板、而且基础父类的原型对象
  //构造函数 、原型对象、实例对象的关系
  //1、构造函数.prototype = 原型对象
  //2、原型对象.constructor = 构造函数(模板)
  //3、原型对象.isPrototypeOf(实例对象)
  //4、构造函数.isInstannceOf(实例对象)
  
  //父类的构造函数
  function Father(name){
   this.name=name  
  }
  
  //父类的原型对象
  Father.prototype={
   constructor:Father,
   say:function(){
    console.log('i am '+this.name)
   }
  }
  
  //子类的构造函数
  function Child(name){
   this.name=name
  }

  
  //子类的原型对象 指向 父类的实例(实现了js的继承)
  Child.prototype=new Father()
  var c1=new Child('child')
  //1、子类的原型对象 包含 一个指向 父类原型的指针
  console.log(Father.prototype.isPrototypeOf(c1))
  //2、子类的原型对象 包含一个指向父类构造函数的指针
  console.log(c1.constructor)
  
  //实现js继承
  console.log(c1.name)
  c1.say()
#类继承:只继承父类模板,不继承原型对象(借用构造函数的方法实现继承)

  //父类的构造函数
  function Father(name){
//   this.name=name
   this.name=name
  }
  
  //父类的原型对象
  Father.prototype={
   constructor:Father,
   say:function(){
    console.log('i am '+this.name)
   }
  }
  //子类的构造函数
  function Child(name,age){
   //call apply 扩展父类模板使用范围
   Father.call(this,name)
   this.age=age
  }
  
  var c1=new Child('li4',21)
  console.log(c1.name)
  console.log(c1.age)
  c1.say()   //报错,无法继承父类的原型对象

   
#混合继承:继承了两次父类构造函数,继承一次父类的原型对象

  //类继承:只继承父类模板,不继承原型对象(借用构造函数的方法实现继承)  
  //子类的构造函数
  function Child(name,age){
   //call apply 扩展父类模板使用范围
   Father.call(this,name)
   this.age=age
  }
  
  //原型继承:子类的原型 包含一个指向父类原型对象的指针;子类的原型 包含一个指向父类构造函数的指针
  Child.prototype=new Father()
  
  var c1=new Child('li4',21)
  console.log(c1.name)
  console.log(c1.age)
  c1.say()