zoukankan      html  css  js  c++  java
  • 原型和构造函数(1)

    构造函数的形式

    1,使用new关键字创建对象

    2,使用构造函数,把新创建出来的对象,赋值给构造函数内的this

    3,在构造函数内使用this为新创建出来的对象新增成员

    4,默认返回新创建的这个对象

         function Animal(name,type,){
             this.name =name;
             this.type =type;
             this.barkWay = function(){
                 console.log('汪汪汪')
             }
         }
         var  dog =new Animal('大黄','dog');
         dog.barkWay();//汪汪汪

    注意:如果想使用正常的函数一样使用构造函数

    1,构造函数中的this将不再指向新创建出来的对象

    2,构造函数中的this这个时候多指向window对象,当使用this给对象添加成员的时候,全部添加到window上

    构造函数存在的问题

    构造函数中的方法,每新创建一个对象的时候,该对象都会重新创建方法,每个对象独占一个方法,但是该方法内容完全相同,所以造成资源浪费

    function Animal(){
        this.name = '大黄';
        this.type ='dog';
        this.age =15;
        this.bark = function(){
            console.log('汪汪汪')
        }
    }
    var dog = new Animal();
    var cat = new Animal();
    
        dog.bark();//汪汪汪
        cat.bark();//汪汪汪

    解决方法1

    将构造函数内的房进行提取放到构造函数外面,在构造函数内部引用,那么创建出来的对象,都会指向构造函数外面的这个函数,达到共享的目的

    function barkWay(){
           console.log(this.type +this.yell)
       }
    
       function  Animal(name,type,yell){
           this.name = name;
           this.type = type;
           this.yell =yell;
           this.bark =barkWay;
       }
       var dog = new Animal('大黄','狗','汪汪汪');
       var cat = new Animal('小花','猫','喵喵喵');
       cat.bark();//猫喵喵喵
       dog.bark();//狗汪汪汪

    问题:全局变量增多,造成全局变量污染,代码结构混乱,不易维护

    解决方法2

    使用原型

     function  Animal(name,type,yell){
           this.name = name;
           this.type = type;
           this.yell =yell;
       }
       Animal.prototype.bark  =function(){
         console.log(this.type + this.yell)
       };
       var dog = new Animal('大黄','狗','汪汪汪');
       var cat = new Animal('小花','猫','喵喵喵');
       cat.bark();//猫喵喵喵
       dog.bark();//狗汪汪汪

    原型: 在构造函数创建出来的时候,系统会默认的创建并关联一个对象,这个对象就是原型,原型对象默认是空对象

    原型的作用:原型中的成员,可以被使用和它关联的构造函数创建出来的所有对象共享

    当使用对象访问属性和方法的时候,会首先在对象内部进行查找,如果找到了,就直接使用,如果没有找到,就去原型中查找,查找到之后使用,如果原型中没有,如果是属性就是undefined,如果是方法就是报错

    function Person(name,age,sing){
          this.name = name ;
          this.age =age;
          this.sing =sing;
      }
      Person.prototype.sayHello = function(){
        console.log("你好我是"+this.name);
    };
      Person.prototype.singName = function(){
          console.log(this.sing)
      };
      var p = new Person('张学友',18,'一千个伤心的理由');
      var p1 = new Person('刘德华',28,'忘情水');
    
         p.sayHello();//你好我是张学友
         p1.sayHello();//你好我是刘德华
    
         p.singName();//一千个伤心的理由
         p1.singName();//忘情水

    原型对象的使用

     1,使用对象的动态特性,为原型对象添加成员

     2, 直接替换原型对象

     如果使用第二种方法使用原型,会出现如下问题

    在替换原型之前创建的对象和在替换原型之后的创建的对象的原型,,不是同一个

    function Person(name,age,sing){
          this.name = name ;
          this.age =age;
          this.sing =sing;
      }
      Person.prototype.sayHello = function(){
        console.log("你好我是"+this.name);//你好我是刘能
    };
       var p = new Person('刘能',18,'male');
           p.sayHello();
       Person.prototype ={
           msg:'你猜我在不在'
       };
       var p1 =new Person('刘二狗',24,'male');
       console.log(p1.msg);//你猜我在不在
       p1.sayHello();//Uncaught TypeError: p1.sayHello is not a function
        p.sayHello();//Uncaught TypeError: p.sayHello is not a function

    使用原型的注意事项

    1,使用对象访问属性的时候,如果在本身内找不到就 回去原型中查找,但是使用点语法进行属性赋值的时候,并不会去原型中进行查找,使用点语法赋值的时候,

    如果对象不存在该属性,就会给该对象新增该属性,而不会修改原型中的属性

     function Person(){
    
     }
     Person.prototype.name ="张三";
     Person.prototype.age =18;
     var  p = new Person();
     console.log(p.name);//张三
     p.name ="李四";
     console.log(p.name);//李四
     var p1 =new Person();
     console.log(p1.name)//张三

    2,如果在原型中的属性是引用类型的属性,那么所有对象共享该属性,并且一个对象修改了该引用类型中的成员,其他都会受到影响

     function Person(){
    
     }
     Person.prototype.name ="张三";
     Person.prototype.age =18;
     var x = {
         brand:'奥迪',
         type:'A7'
     };
     Person.prototype.car =x;
     var  p = new Person();
     console.log(p.car.brand);//奥迪
     Person.prototype.car ={
         brand: 'BYD'
     };
     var p1 =new Person();
         console.log(p.car.brand);//BYD
         console.log(p1.car.brand);//BYD

    3,一般情况下不会讲属性添加到原型中,只会将需要共享的方法,添加到原型对象中

  • 相关阅读:
    严格模式
    es6模块与 commonJS规范的区别
    Javascript内置对象、原生对象、宿主对象关系
    实现继承的几种方式
    创建对象的一些方式
    null的小扩展
    getElementById的缩略
    你真的知道为什么不推荐使用@import?
    换行与不换行
    transition与animation
  • 原文地址:https://www.cnblogs.com/lrgupup/p/9283082.html
Copyright © 2011-2022 走看看