js面向对象(继承,原型和fengzhuang)

来源:互联网 发布:常用路由选择算法 编辑:程序博客网 时间:2024/06/01 10:20
// -------将猫看成一个对象
    var Cat={
      name:'',
      color:''
    }
    console.log(Cat);
    var cat1={};
    cat1.name="huang";
    cat1.color='yellow';
    var cat2={};
    cat2.name="chen";
    cat2.coloe='white';
    console.log(cat1);
    console.log(cat2);
    // ------------写成函数,返回一个对象
    function Cat(color,name){
      return{
        color:color,
        name:name
      }
    }
    var cat1=Cat("huang1","yellow");
    console.log(cat1);
    var cat2=Cat('chen1','white');
    console.log(cat2);
    // -----------构造函数:初始化新对象,计算结果就是这个新对象的值,显示返回新的对象。this指向新创建的对象
    // function Cat(name,color){
      this.name=name;
      this.color=color;
      this.type='猫科动物';
      this.eat=function(){
        console.log('hello');
      }
    }
    var cat1=new Cat('huang2','yellow');
    var cat2=new Cat('chen2','white');
    cat1.eat();
    console.log(cat1.type);
    // ---每个构造函数都有prototype属性,指向另一个对象。这个对象的属性和方法都会被构造函数的实例继承
    // 这就意味着我们可以把不变的属性和方法直接定义在prototype对象上。
    function Cat(name,color){
      this.name=name;
      this.color=color;
    }
    Cat.prototype.type='猫科动物';
    Cat.prototype.eat=function(){
      console.log('bbbbb');
    }
    var cat1=new Cat('hhhhh','fffff');
    var cat2=new Cat('ccccc','wwwww');
    console.log(cat1);
    console.log(cat2);
    cat1.eat();
    console.log(cat1.eat==cat2.eat);
    //---isPrototypeOf()这个方法是用来判断某个prototype对象和实例之间的关系
    console.log(Cat.prototype.isPrototypeOf(cat1));
    //hasOwnProperty()判断某个属性到底是本地属性还是继承自prototype对象的属性
    console.log(cat1.hasOwnProperty('name'));
    console.log(cat1.hasOwnProperty('type'));
    // ---------构造函数的继承
    function Animal(){
      this.species='动物';
    }
    function Cat(name,color){
      this.name=name;
      this.color=color;
    }
    // ----任何一个prototype对象都有一个constructor属性,指向它的构造函数
    // ---每个实例对象都有constructor属性
    Cat.prototype=new Animal();
    Cat.prototype.constructor=Cat;
    var cat1=new Cat('hhh','kkk');
    console.log(Cat.prototype.constructor);
    console.log(cat1.constructor);
    // 总结:如果替换了prototype对象,必须手动纠正。例如:
    o.prototype={};
    o.prototype.constructor=o;
    // 直接继承(由于不变的属性可以直接写入prototype)存在一个缺点:Animal.prototype.constructor和Cat.prototype.constructor指向同一个
    function Animal(){};
    Animal.prototype.species='物种1';
    Cat.prototype=Animal.prototype;
    Cat.prototype.constructor=Cat;
    var cat1=new Cat('hhh','kkk');
    console.log(cat1.species);
    console.log(Animal.prototype.constructor);
    // ----利用空对象作为中介
  var F=function(){};
  F.prototype=Animal.prototype;
  Cat.prototype=F.prototype;
  Cat.prototype.constructor=Cat;
  var cat1=new Cat('hhh','kkk');
  console.log(cat1.species);
  console.log(F.prototype.constructor);
  // 封装成一个方法
  function extend(Child,Parent){
    var F=function(){};
    F.prototype=Parent.prototype;
    Child.prototype=new F();
    Child.prototype.constructor=Child;
    Child.uber=Parent.prototype;
  }
  extend(Cat,Animal);
  var cat1=new Cat('hhh','kkk');
  console.log(cat1.species);
  var chinese={nation:'中国1',name:'热敏',age:'90',birthplace:['湛江','珠海','广州']};
  var doctor={career:'医生'};
  //-----使用prototype链实现
  function object(o){
    function F(){};
    F.prototype=o;
    return new F();
  }
  //-------把父对象的属性都赋给子对象,也能实现继承
  //这样的拷贝有一个问题,如果父对象的属性等于数组或另一个对象,实际上,子对象获得的只是一个内存地址,
  //而不是真正的拷贝,因此存在父对象被篡改的可能。
  function extendCopy(p){
    var c={};
    for(var i in p){
      console.log(p[i]);
      c[i]=p[i];
    }
    c.uber=p;//上一级父对象
    return c;
  }
  //------深拷贝,实现真正意义上的数组和对象的拷贝
  function deepCopy(p,c){
      var c=c||{};
      for(var i in p){
        if(typeof p[i]==='object'){
          c[i]=(p[i].constructor===Array)?[]:{};
          deepCopy(p[i],c[i]);
        }else{
          c[i]=p[i];
        }
      }
      return c;
  }
  var doctor=deepCopy(chinese);
  doctor.birthplace.push('厦门');
  console.log(doctor.birthplace);
  console.log(chinese.birthplace);