创建对象的几种模式

来源:互联网 发布:途虎 淘宝 编辑:程序博客网 时间:2024/06/03 20:37

对象创建方法其实主要有两种最简单的方式:

  1. 创建一个Object实例
var person = new Object();person.name = 'jinghong';person.age = 22;person.sayName = function(){    alert(this.name);  }
  1. 对象字面量
    var person = {
    name = ‘jinghong’,
    age: ‘22’
    }

一、工厂模式

function creatPerson(name, age, job){  var obj = new Object();  obj.name = name;  obj.age = age;  obj.job = job;  obj.sayName = function(){    alert(this.name);  }  return obj;}var person1 = createPerson('jinghong', 22, 'software engnieer');var person2 = createPerson('tiantian', 21, 'teacher');

二、构造函数模式

//构造函数模式function Person(){  this.name = name;  this.age = age;  this.job = job;  this.sayName = function(){    alert(this.name);  }}var person1 = new Person('jinghong', 22, 'software engnieer');var person2 = new Person('tiantian', 21, 'teacher');

注意: 构造函数只是一些使用new 操作符时,被调用的普通函数,并不是一个类。任何函数被new调用时,它就是构造函数;
当一个函数被new表达式中被调用时,他是一个构造函数,他会初始化创建一个新的对象。

使用new来调用函数时会发生一下操作:

  1. 创建一个新的对象
  2. 将构造函数的作用域赋给这个对象(因此这个新对象会绑定到构造函数的this)
  3. 执行构造函数中的代码(为这个新的对象添加属性和方法)
  4. 返回新的对象

在前面的例子中,person1,person2分别是Person的实例;这两个实例对象都有一个constructor属性,该属性指向Person;

console.log(person1.constructor);//Person
console.log(person2.constructor);//Person

构造函数模式和工厂模式不同的地方是,可以将实例标识为一种特定的类型,

console.log(person1 intanceof Object);  //trueconsole.log(person1 intanceof Person);  //true

构造函数模式的缺点:

构造函数的每个实例中实际上都包含不同的Function实例,即:person1.sayName != person2.sayName
创建两个完成同样任务的Function实例的确没有必要,所以可以通过把函数定义转移到函数外面进行,来解决这个问题:

funtion Person(name, age, job){      this.name = name;      this.age = age;      this.job = job;      this.sayName = sayName;//一个函数的指针  }function sayName(){  alert(this.name); } var person3 = new Person('person3', 21, 'doctor'); person3.sayName();//person3

三、原型模式

function Person(){}Person.prototype.name = 'jinghong';Person.pertotype.age = 29;Person.prototype.job = 'software Engineer';Person.pertotype.sayName = funtion(){  alert(this.name); }var person1 = new Person();var person2 = new Person();person1.sayName();//'jinghong';person2.sayName();//'jinghong'

构造函数为空函数,但是仍然可以通过new构造函数来创建一个新的对象,并且这些对象还会具有相同的属性和方法,但是与构造函数不同的是,新对象的属性和方法是所有实例共享的,所以person1和person2的sayName()方法是同一个函数;

什么是原型对象

在任何时候,只要创建一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象,原型对象在默认情况下拥有一个constructor属性,这个属性指向所在函数的指针,例如:Person.prototype.constructor指向person;
这里写图片描述

不能通过对象实例重写原型中的值

如果我们在实例中添加了一个属性,而属性与实例原型中的一个属性同名,那么我们就在实例中创建该属性,该属性会自动屏蔽原型中的那个属性。

简单的原型语法

 function Person(){ } Person.prototype{    name : 'jinghong',    age: 21,    sayName: function(){        alert(this.name);    } }

原生对象的原型

通过給原生对象的原型对象添加或者修改方法,可以給基本包装类型添加或者修改方法;
例如:給基包装类型String添加名为startsWith()方法,检测一个字符串是否以某个特定的字符开始

String.prototype.stratWith = function(text){    return this.indexOf(text) == 0;     }

四、组合使用构造函数模式和原型模式

构造函数用于定义实例属性,原型模式用于定义方法和共享属性,这样所有实例都拥有自己的一份实例属性的副本,同时并拥有对共享方法的引用,最大限度的节省了内存

function Person(name, age, job){    this.name = name;    this.age = age;    this.job = job;    this.friends = ['a', 'b', 'c']}Person.prototype = {  constructor : Person;  sayName : function(){     alert(this.name);  }var person1 = new Person('jinghong', 21, 'engineer');var person2 = new Person('wenjuan', 21, 'engineer');person1.friends.push('d');console.log(person1.friends);//'a', 'b', 'c','d'console.log(person2.friends);//'a', 'b', 'c'console.log(person1.friends === person2.friends);//falseconsole.log(person1.sayName === person2.sayName);//true

五、动态原型模式

function Person(name, age, job){  //属性   this.name = name;   this.age = age;   this.job = job;  //方法  if (typeof this.name != 'function'){   Person.prototype.sayName = function(){        alert(this.name);      }    }  }

在上述代码中只有当以前的原型对象没有sayName方法时,才在原型链中添加sayName方法,并且这段代码只能在初次调用时才会执行,以后原型已经完成初始化,并且以后生成的实例都将具有修改后的sayName方法;

六、寄生构造函数模式

七、稳妥构造函数模式

原创粉丝点击