js想要继承,先创建一个父类。
function Person(name,age){
     this.name = name;  ----属性
     this.age = age;      
     this.sayThing = function(){  ---实例方法
    console.log('say something');
   }
 }
1、原型链继承
原型链是一种关系,实例对象和原型对象之间的关系,关系是通过原型(__proto__)来联系的。
实例对象中有__proto__,是对象,叫原型,不是标准的属性,浏览器使用,并且有的游览器不支持。
构造函数中有prototype属性,也是对象,叫原型。
注意 原型中的方法是可以互相访问的。
原型的简单语法:
1、利用原型共享数据
Person.prototype.height = '180cm';
Person.prototype.eat=function(){
   console.log('吃早餐');  
  this.play();
}
Person.prototype.play = function(){
  console.log('打球');
}
var person1 = new Person('张三',20);
2、写法二:直接这么赋值,会导致constructor构造器属性消失,需要手动修改构造器指向。
function Student(name,age,sex){ this.name=name; this.age=age; this.sex=sex; } Student.prototype={
constructor:Student, height:"188", weight:"55kg", study:function(){ console.log("好好学习i") } } var stu=new Student("小红",20,"男") console.dir(stu)
构造函数和实例对象和原型对象之间的关系
1、构造函数可以实例化对象
2、构造函数中有一个属性叫prototype,是构造函数的原型对象
3、构造函数的原型对象(prototype)中有一个constructor 构造器,这个构造器指向的就是自己所在的原型对象所在的构造函数
4、实例对象的原型对象(__proto__) 指向的是该构造函数的原型对象(prototype)
5、构造函数的原型对象(prototype)中的方法是可以被实例对象直接访问 
更改原型链指向:
  function Person(age) {
    this.age = age;
  }
  Person.prototype.eat = function () {
    console.log('吃萝卜');
  }
  function Student(name) {
    this.name = name;
  }
  Student.prototype.play = function () {
    console.log('打篮球');
  }
  Student.prototype = new Person(19);
  var stu = new Student('张三');
  console.log('stu.age=', stu.age);   --- 19
  console.log('stu.name=', stu.name);  ----- 张三
  console.log(stu.eat);  ----- function(){}
  console.log(stu.play);  ----- undefined
原型链是可以更改指向的,定义的构造函数 Student, 更改原型链指向Person,则指向了Person的构造函数。Person的 eat 方法可以得到,此时的 play 方法 因为指向改变了,所以找不到为undefined。但是构造函数Person 和 Student 里面的独立属性是都继承的。
3、构造函数继承
// 定义一个动物类
function Animal (name) {
  // 属性
  this.name = name || 'Animal';
  // 实例方法
  this.sleep = function(){
    console.log(this.name + '正在睡觉!');
  }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + '正在吃:' + food);
};
function Cat(name){ Animal.call(this);
Person.call(this); ------- 可以引用多个父类构造函数 this.name = name || 'Tom'; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true
特点:
- 子类实例共享父类引用属性。
- 创建子类实例时,可以向父类传递参数
- 可以实现多继承(call多个父类对象)
缺点:
- 实例并不是父类的实例,只是子类的实例
- 只能继承父类的实例属性和方法,不能继承原型属性/方法
- 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
4、组合继承(组合原型链继承和借用构造函数继承)
  function Person(name) {
    this.name = name;
    this.sum = function () {
      return 'hello';
    }
  }
  function SubType(name) {
    Person.call(this, name)
  }
  SubType.prototype = new Person();
  var sub = new SubType('李四');
  console.log('sub.name=', sub.name);    --- 李四
  console.log('sub.sum =', sub.sum());   ---- hello
重点:结合了两种模式的优点,传参和复用
特点:1、可以继承父类原型上的属性,可以传参,可复用。
   2、每个新实例引入的构造函数属性是私有的。
缺点:调用了两次父类构造函数Person()(耗内存),子类的构造函数会代替原型上的那个父类构造函数。
 
                    
                     
                    
                 
                    
                 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号