1、基于Object对象

var person = new Object();
person.name = 'My Name';
person.age = 18;
person.getName = function(){
  return this.name;
}

2、对象字面量

假定我们把人看成一个对象,它有"名字"和"年龄"两个属性。

var Person = {
  name : '',
  age : ''
}   

现在,我们需要根据这个原型对象的规格(schema),生成两个实例对象。

var person1 = {}; // 创建一个空对象    
person1.name = "大毛"; // 按照原型对象的属性赋值    
person1.age = "19";  
var person2 = {};    
person2.name = "二毛";    
person2.age= "30";

  

3、工厂模式

我们可以写一个函数,解决代码重复的问题。  
  function Person(name,color) {     
    return {      
      name:name,       
      age:age    
    }   
  }
或者:

  function Person(name,age) {     
    var person = new Object();
    person.name = name;
      person.age = age;
    return person; 
  }

然后生成实例对象,就等于是在调用函数:   
  var person1 =Person("大毛","19");   
  var person2 = Person("二毛","30");

  

  4、构造函数模式

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.getName = function () {
        return this.name;
    }
}
var person1 = new Person('Jack', 19, 'SoftWare Engineer');
var person2 = new Person('Liye', 23, 'Mechanical Engineer');

使用自定义的构造函数(与普通函数一样,只是用它来创建对象),定义对象类型(如:Person)的属性和方法。它与工厂方法区别在于: 没有显式地创建对象 直接将属性和方法赋值给this对象; 没有return语句;
此外,要创建Person的实例,必须使用new关键字,以Person函数为构造函数,传递参数完成对象创建;实际创建经过以下4个过程: 1.创建一个对象 2.将函数的作用域赋给新对象(因此this指向这个新对象,如:person1) 3.执行构造函数的代码 4.返回该对象 上述由Person构造函数生成的两个对象person1与person2都是Person的实例,因此可以使用instanceof判断,并且因为所有对象都继承Object,因此person1 instanceof Object也返回真: alert(person1 instanceof Person);//true; alert(person2 instanceof Person);//true; alert(person1 instanceof Object);//true; alert(person1.constructor === person2.constructor);//ture;
虽然构造函数方式比较不错,但也存在缺点,那就是在创建对象时,特别针对对象的属性指向函数时,会重复的创建函数实例,以上述代码为基础,可以改写为: function Person(name,age,job){   this.name = name;   this.age = age;   this.job = job;   this.getName = new Function () {//改写后效果与原代码相同,不过是为了方便理解     return this.name;   } } 上述代码,创建多个实例时,会重复调用new Function();创建多个函数实例,这些函数实例还不是一个作用域中,当然这一般不会有错,但这会造成内存浪费。当然,可以在函数中定义一个getName = getName的引用,而getName函数在Person外定义,这样可以解决重复创建函数实例问题,但在效果上并没有起到封装的效果,如下所示: function Person(name,age,job){   this.name = name;   this.age = age;   this.job = job;   this.getName = getName; } function getName() {//到处是代码,看着乱!!   return this.name; }

  

5、原型模式

     JS每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,它是所有通过new操作符使用函数创建的实例的原型对象。原型对象最大特点是,所有对象实例共享它所包含的属性和方法,也就是说,所有在原型对象中创建的属性或方法都直接被所有对象实例共享。

 

function Person(){
}
Person.prototype.name = 'Jack';//使用原型来添加属性
Person.prototype.age = 29;
Person.prototype.getName = function(){
  return this.name;
}

var person1 = new Person();
alert(person1.getName());//Jack
var person2 = new Person();
alert(person1.getName === person2.getName);//true;共享一个原型对象的方法

  

6、组合构造函数及原型模式

      目前最为常用的定义类型方式,是组合构造函数模式与原型模式。构造函数模式用于定义实例的属性,而原型模式用于定义方法和共享的属性。结果,每个实例都会有自己的一份实例属性的副本,但同时又共享着对方方法的引用,最大限度的节约内存。此外,组合模式还支持向构造函数传递参数,可谓是集两家之所长。

 

function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.lessons = ['Math', 'Physics'];
}

Person.prototype = {
  constructor: Person,//原型字面量方式会将对象的constructor变为Object,此外强制指回Person
  getName: function () {
    return this.name;
  }
}

var person1 = new Person('Jack', 19, 'SoftWare Engneer');
person1.lessons.push('Biology');
var person2 = new Person('Lily', 39, 'Mechanical Engneer');
alert(person1.lessons);//Math,Physics,Biology
alert(person2.lessons);//Math,Physics
alert(person1.getName === person2.getName);//true,//共享原型中定义方法

  

 

  

 

posted on 2017-05-02 10:43  前端小透明  阅读(176)  评论(0编辑  收藏  举报