汉莫拉比

javascript笔记3-面向对象的程序设计-创建对象

javascript的对象:无序属性的集合,而每个属性可以包含基本值、对象或者函数。举例:

1  var person = new Object();
2         person.name = "Nicholas";
3         person.age = 29;
4         person.job = "Software Engineer";
5         person.sayName = function(){
6             alert(this.name);
7         };
8         
9         person.sayName();

person是一个对象,name、age、job、sayName都是对象的属性。其中,sayName是一个特殊的属性,它有一个函数。

实际上,函数也是一个Function类型,是个引用类型,而对象也是一个引用类型,如此可以重新描述javascript对象:对象拥有一些属性,每个属性又可以包含基本类型、引用类型。

  1. 对象的创建:
    • 创建一个Object实例,然后添加属性:
      1  var person = new Object();
      2         person.name = "Nicholas";
      3         person.age = 29;
      4         person.job = "Software Engineer";
      5         person.sayName = function(){
      6             alert(this.name);
      7         };
      8         
      9         person.sayName();

       

    • 直接使用字面量:
      var person={
        name : "JAY",
        age : 29,
        job : 'singer',
        sayName : function(){
         alert(this.name);
       }   
       
      };

       

  2. 创建对象的策略
    • 工厂模式把创建对象的过程封装起来,让代码更加整洁):
      function createPerson(name, age, job){
                  var o = new Object();
                  o.name = name;
                  o.age = age;
                  o.job = job;
                  o.sayName = function(){
                      alert(this.name);
                  };    
                  return o;
              }
              
              var person1 = createPerson("Nicholas", 29, "Software Engineer");
              var person2 = createPerson("Greg", 27, "Doctor");

      缺点:对象是创建了,但是如果你问person1、person2是什么类型的,无法识别出。解决方法:构造函数模式。

    • 构造函数模式:
      function Person(name, age, job){
                  this.name = name;
                  this.age = age;
                  this.job = job;
                  this.sayName = function(){
                      alert(this.name);
                  };    
              }
              
              var person1 = new Person("Nicholas", 29, "Software Engineer");
              var person2 = new Person("Greg", 27, "Doctor");
      • 优点:可以知道对象的类型(Person)。
        构造函数也是函数。
        
        任何函数使用new就变成了构造函数(只不过约定俗成构造函数第一个字母大写),不用new就是一般函数。 
      • 缺点:sayName是一个函数(函数是对象,是引用类型),每次new一个Person,都要重新创建sayName的实例。解决方法:原型模式。
    • 原型模式实例共享属性和方法

      创建函数时会加属性,而每个函数都有一个隐藏属性:prototype(原型)。
      prototype是一个指针,指向一个对象,该对象包含了所有实例共享的一些属性和方法。

      function Person(){
              }
              
              Person.prototype.name = "Nicholas";
              Person.prototype.age = 29;
              Person.prototype.job = "Software Engineer";
              Person.prototype.sayName = function(){
                  alert(this.name);
              };
              
              var person1 = new Person();
              person1.sayName();   //"Nicholas"
              
              var person2 = new Person();
              person2.sayName();   //"Nicholas"
            
              alert(person1.sayName == person2.sayName);  //true

      跟父类很类似。这时,person1和person2的sayName是同一个引用。

      • 创建一个新函数A,就会自动为该函数创建prototype属性。这个属性指向该函数的原型对象B。
      • B有一个constructor属性,该属性包含一个指向A的指针。

      • 通过B.isPrototypeof(Person1)来确定原型关系。
      • 不能通过对象实例来修改原型的属性值。
        function Person(){
                }
                
                Person.prototype.name = "Nicholas";
                Person.prototype.age = 29;
                Person.prototype.job = "Software Engineer";
                Person.prototype.sayName = function(){
                    alert(this.name);
                };
                
                var person1 = new Person();
                var person2 = new Person();
                
                person1.name = "Greg";
                alert(person1.name);   //"Greg" ?from instance
                alert(person2.name);   //"Nicholas" ?from prototype

         

      • 更简单的原型语法:
         function Person(){
                
        }
                
        Person.prototype = {
                    name : "Nicholas",
                    age : 29,
                    job: "Software Engineer",
                    sayName : function () {
                        alert(this.name);
                    }
         };

        该方式中,constructor属性不再指向Person。(因为创建一个函数会生成一个prototype属性,该属性指向原型对象的地址,原型对象的constructor属性又指向Person,而在本方式中,prototype被重写,那么导致生成的原型对象B不是原汁原味的原型对象了,这么一来,B的constructor也就不再指向A了)。

 

      

 

  

   

posted on 2016-02-09 20:47  搬砖的小学生  阅读(815)  评论(0编辑  收藏  举报