你的位置:首页 > Java教程

[Java教程]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了)。