JavaScript中的的面向对象中的一些知识

JavaScript中的的面向对象中的一些知识

function Cat(name,age){
       return {
              name:name,
              age:age   
       }
    }
    
//构造函数
function Dog(name,age){ this.name=name; this.age=age; } function show(){ var c1=new Cat("cat1",18); var c2=new Cat("cat2",19); //Javascript还提供了一个instanceof运算符,验证原型对象与实例对象之间的关系。 alert(c1 instanceof Cat); //false alert(c2 instanceof Cat); //false var d1=new Dog("dog1",18); var d2=new Dog("dog2",19); alert(d1 instanceof Dog); //true alert(d2 instanceof Dog); //true }

构造函数方法很好用,但是存在一个浪费内存的问题。

所以就有了prototype对象了

    function Dog(name,age){
          this.name=name;
          this.age=age;    
    }
    Dog.prototype.type="Animal";
    //isPrototypeOf();某个prototype对象和某个实例之间的关系
    function show(){
        var dog=new Dog("yuanzhangliu",18);
        //alert(Dog.prototype.isPrototypeOf(dog));
        //true;
        //判断对象的实例时属于本地还是prototype对象的属性
        alert(dog.hasOwnProperty("name")); //true
        alert(dog.hasOwnProperty("type")); //false
        
        //那么我们的in运算符号可以判断,某个实例是否含有属性;不管本地还是prototype中滴
        alert("name" in dog); //true
        alert("type" in dog); //true
        //或者直接使用我们for循环来遍历滴呀
        for(var prop in dog){
           alert(prop);    
        }
    }

第二部分:构造函数之间的继承

call apply 实现继承

  function Animal(){
      this.species="Animal";  
      this.fun=function (){
        alert("eat");  
      }
  }
  
  function Dog(name,age){
      this.name=name;
      this.age=age;
      Animal.call(this);
      //Animal.call(this,arguments); 将Dog中的参数传递过去,
      //让它(arguments)中可以使用滴呀 具体的额,后面用到再呵呵呵
  }
  function show(){
      var d=new Dog("dog",12);
      alert(d.species);
      d.fun();
  }
    

prototype来是实现滴呀

  function Animal(){
      this.species="Animal";  
      this.fun=function (){
        alert("eat");  
      }
  }
  
  function Dog(name,age){
      this.name=name;
      this.age=age;
  }
  function show(){
      //第一步:
       Dog.prototype=new Animal();
       Dog.prototype.constructor=Dog; //这不还是很重要的
       //防止继承链的紊乱
       
       //再实际的开发中如果我们替换了原来函数对象的prototype
       //我们也该constructor,(正确的说叫还原constructor)
       //o.prototype={};
       //o.prototype.consturtor=o
       var d=new Dog("yuanzhang.liu",18);
       d.fun();
  }

方法三

  function AnimalOld(){
      this.species="Animal";  
      this.fun=function (){
        alert("eat");  
      }
  }
  //将他改造成如下:
  function Animal(){
  
  }
  Animal.prototype.species="Animal";
  Animal.prototype.fun=function (){
    alert("eat");  
  }
  function Dog(name,age){
      this.name=name;
      this.age=age;
  }

  function show011(){
    //这样我们就省去了new Animal();
     Dog.prototype=Animal.prototype;
     Dog.prototype.constructor=Dog; //这句话也将我们Animal.prototype.constructor 改变了滴呀
     //解决方法就是利用空的对象做为介质滴呀
    
    
     var d=new Dog("yuanzhangliu",18);
     d.fun(); 
     //这样我们的额Dog.prototype 和 Animal.prototype 就指向了同一个
     //对象,任何一个对象的修改,都会反映到另外一个对象上滴呀
  }
    function F(){
    
    }
    function show(){
     F.prototype=Animal.prototype;
     Dog.prototype=new F();
     Dog.prototype.constructor=Dog;
     var d=new Dog("yuanzhangliu",18);
     d.fun(); 
     //这样我们的额Dog.prototype 和 Animal.prototype 就指向了同一个
     //对象,任何一个对象的修改,都会反映到另外一个对象上滴呀
  }

我们把上面的的方法总结和改进一下就可以提取出一个通用的方法滴呀

 function extend(Child,Parent){
      function Kong(){};
      Kong.prototype=Parent.prototype;
      Kong.prototype.constructor=Kong;
      Child.prototype=new Kong();
      Child.prototype.constructor=Child;
 }

方式四:我们可以通过拷贝的方式进行滴呀;

function Person(name,age){
     this.name=name;
     this.age=age;
     this.fun=function (){
        alert("fun"); 
     }
 }
 
 Person.prototype.protoFun=function (){
     alert("prototypeInfo"); 
 }
 function Dog(name,age){
     this.name=name;
     this.age=age;
 }
 //接下来,我们通过拷贝来实现继承id呀
 function extend2(Child,Parent){
    //同样的,使用这种方式实现继承滴呀;
    //父类的属性,必须设置在prototype上才被子类继承
    var p=Parent.prototype;
    var c=Child.prototype;
    
    for(var i in p){
      c[i]=p[i];//还要拷贝它的值滴呀;    
    }
 }

   function show(){
     extend2(Dog,Animal);
     var d=new Dog("yuanzhangliu",18);
     d.protoFun();
     d.fun();//无法调用滴呀   
   }

非构造函数的方式来实现继承继承滴呀

   //非构造函数的方式实现继承滴呀;
   var chinese={
          nation:'中国'
       };
   var Doctor={
        career:'医生'
       }
       //这两个都是普通的对象,不是构造函数,无法使用构造函数的方式来实现继承滴呀
       //将两个对象通过prototype链,连接在一在一起的呀;

实现方式

 function object(parent){
       function F(){
        //利用它的原型链,将他们连接在一起的滴呀
       }
       F.prototype=parent;
       var son=new F();
       return son;//这样就返回了父级对象滴呀
    }
    
    //使用的时候;
    var Chinese={
      nation:'中国'    
    }
    var Doctor=object(Chinese);
    Doctor.career='医生';
    
    alert(Doctor.nation);
    //原来尼玛,是这样写的滴呀;

还用一种方式:

    function extendCopy(parent){
       var c={}; //空对象介质;
       for(var i in parent){
         //循环遍历出它的属性的呀; 子对象获取的是父对象的一个内存地址
         c[i]=parent[i];   
       }
       return c;
    }
    //使用的时候;
    var Chinese={
       nation:'中国'    
     }
    var Doctor=extendCopy(Chinese);
    Doctor.career='医生';
    alert(Doctor.nation);

缺点:浅拷贝,子对象获取的是父对象的一个内存地址,当子对象改变的同时也就改变了父级对象滴呀

Chinese.birthPlaces=['日本','京都','大阪'];
    var Doctor=extendCopy(Chinese);
    Doctor.birthPlaces.push('眉山');
    
    alert(Chinese.birthPlaces);//父级的也被改变了
    alert(Doctor.birthPlaces);
    //他们的结果都是:'日本','京都','大阪','眉山'

既然有浅拷贝,当然就有我们的深拷滴呀

     function deepCopy(parent,son){
         var son=son || {};
         for(var i in parent){
            if(typeof parent[i]==='object'){
                son[i]=(parent[i].constructor===Array)?[]:{};
                //然后继续拷贝滴呀
                 deepCopy(parent[i],son[i]);//进一步的遍历滴呀
            }else{
              son[i]=parent[i];    
            }
         }
      }
      //目前jquery 就使用的这种方式实现继承id呀

这样我们的面向对象的就算是....

原文地址:https://www.cnblogs.com/mc67/p/5182247.html