原型和构造函数(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,一般情况下不会讲属性添加到原型中,只会将需要共享的方法,添加到原型对象中

猜你喜欢

转载自www.cnblogs.com/lrgupup/p/9283082.html