原型对象--继承

来源:互联网 发布:医院网络总监 编辑:程序博客网 时间:2024/06/05 06:31
一、继承的概念

**面向对象的特征就是封装性、继承性和多态性
1、封装:就是将复杂的包裹起来,隐藏起来,让简单的东西预留在外面
2、继承:继承它父级,拿来主义,自己没有,把别人拿过来

   在js中有两种继承模型
   (1)、原型继承:如果需要让一个对象有某一个行为(属性,方法),那可以考虑将这个行为加到原型对象中那么这个对象就是继承自原型对象,获得了该行为。

   (2)、组和继承:将其他的对象中的成员加到自己身上

**组合继承例子:
  var o1={name:"alvin",age:19,gender:"boy"};
  var o2={socre:{
                  math:90,
                  Chinese:100,
                  English:80
                 }
          };
 //让o2继承自o1
 //将o1的成员加到o2上
for(var k in o1){
     o2[k]=o1[k];
}
//由于for in循环中的对象可以随意的替换,因此o2可以继承自任意的对象,因此这个继承方法称为组合式继承。


**希望o2可以继承自任意的对象,所以为简化继承的代码,给o2提供一个方法,叫extend
  var o1={name:"alvin",age:19,gender:"boy"};
  var o2={socre:{
                  math:90,
                  Chinese:100,
                  English:80
                 }
          };
o2.extend=function(obj){
   for (var k in obj){
      this[k]=obj[k];
      }
   };
o2.extend(o1);//继承

o2.extend({
    ID:function(id){},
    tag:function(tag){},
    showErr:function(msg){
        throw new Error(msg);
      }

});



**原型式继承:对象继承自其原型对象,在对象的原型对象中加东西即可
**使用原型对象的方法:
 1、利用对象的动态特性添加成员
  var o={};
  o.name="alvin";


  var Person=function(){};
  Person.prototype.sayHello=function(){
    alert("");
 };
 此时原型对象是对象,可以利用动态特性随时添加成员,添加成员都会被构造函数的对象继承。

 2、利用覆盖原型对象
 var Person=function (){};
 Person.prototype.sayHello=function(){};
 Person.prototype.sayLove=function(){};
//.....Person.prototype重复编写
//如果需要添加的内容非常多


Person.prototype={//此处覆盖了原型对象
    constructor:Person,//加此属性,原型对象变成有constructor属性
    sayHello:funtion(){},
    sayGoodbye:function(){},
    sayLove:function(){}
  };
这里由Person创建出来的对象是什么类型?

var p=new Person();
console.log(p.constructor.name);

//结果Person ,如果不在上面的添加constructor:Person,结果是Object,因为上面Person的原型对象没有constructor,所以去原型对象的原型上找构造函数名,此时原型对象的对象是object,所以打印出来Object
//覆盖原型对象实现继承的时候,一定要给新对象添加一个constructor属性,以便模拟对象的类型,但是如果对对象的类型要求不严格的可以忽略。


3、利用组合式继承添加原型成员
   对象.extend(对象);
   

二、经典继承
1、在实际开发中如果希望获得一个继承自对象o 对象,可以使用Object.create方法,ES5提供的方法,新对象Object.create(作为原型对象的对象)。
   var o1={name:"alvin"};
   var o2=Object.create(o1);//与类型无关,无法判断类型

2、IE不支持create,所以创建一个新对象,让它继承自参数对象;创建新对象就有构造函数;继承对象就有原始对象
function create(obj){
  function F(){}
  //要有继承
  F.prototype=obj;//要有原型,此时F  new出来的对象统统继承obj
  return new F();
}
var o1={name:"alvin"}
var o3=create(o1);
conlose.log(o3);
结果:o3:F   
      name:"alvin"


3、在实际开发中,为了兼容所有浏览器,有两种方法
(1)、用原生对象中提供的方法
 if(!Object.create){
    Object.create=function(obj){
       function F(){}
       F.prototype=obj;
      return new F();
  }
}
var o1={name:"alvin"};
var o4=Object.create(o1);


(2)、无论浏览器是否支持该方法,都应该使用自己定义的方法完成,但是在方法内部,判断浏览器内部是否具有该功能,如果有该功能;则使用浏览器提供的的功能;如果浏览器不支持该功能则自己实现。
 var create=function(obj){
   if(Object.create){//浏览器支持则采用浏览器自己的方法
      return Object.create(obj);
   }
   else{//ie不支持则自己实现
     function F(){};
     F.prototype=obj;
     return new F();
  }
    }
var o5=create(obj);



总结原型式继承:
1、概念:对象继承自原型对象,对象没有的成员,可以由原型对象提供。
2、实现方式
   (1)、动态添加原型对象的成员
   (2)、直接替换原型对象(如果对类型要求严格需要添加constructor属性)
   (3)、利用extend函数给原型对象添加成员。
3、经典的继承代码
   var o1={name:"alvin"};
   var o2=Object.create(o1);
   
o2作为对象,它的原型对象由谁来决定;
o2的原型对象由构造函数的prototype决定;
o2的原型对象就是o1;
所以:o2构造函数的prototype=o1;


**o2没有构造函数:o2是由create函数创建的,那么函数内容有一个构造函数就可以了
var create=function(obj){//create里没有构造函数
   function F(){}//在create里创建一个构造函数
   F.prototype=obj;//把obj变成F构造函数中的原型对象
   return new F();
    }

**浏览器兼容性问题
1、直接交给原生对象,给原生对象提供功能
 if(!Object.create){//如果不支持此方法,因为不是调用,所以不用create()加括号
    Object.create=function(obj){
      function F(){}
      F.prototype=obj;
      return new F();
  }

2、项目复杂的时候,上面的方法混乱
   先考虑浏览器是否有该方法,有就使用浏览器,没有就使用自己实现的
function create(obj){
   if(Object.create){//判断浏览器是否支持
    return Object.create(obj);
}
   else{//浏览器不支持,自己实现   
      function F(){}
      F.prototype=obj;
      return new F();
}

}

   




0 0
原创粉丝点击