1.工厂模式
function createPerson(name){
var o = new object();
o.name=name;
o.sayName=function(){
alert(name);
}
return o;
}
var person=createPerson("Tom");
person.sayName();
工厂模式解决了创建相似对象的要求,但是没有解决对象识别的问题(即无法知道对象的类型)
2.寄生构造函数模式
function Person(name){
var o = new object();
o.name=name;
o.sayName=function(){
alert(name);
}
return o;
}
var person=Person("Tom");
person.sayName();
除了使用new操作符并把使用的包装函数叫做构造函数之外,这个模式跟工厂模式其实是一模一样的,这个模式可以在特殊的情况下用来为对象创建构造函数,例如不能直接修改Array的构造函数,可以使用这个模式。
3.稳妥构造函数模式
function Person(name){
var o = new Object();
o.name="Tom";
o.sayName=function(){
alert(name);
}
return o;
}
var person=Person("Tom");
person.sayName();
这个稳妥没太看出什么节奏来!!!
4.构造函数模式
function Person(name){
this.name=name;
this.sayName=function(){
alert(name);
}
}
var person=new Person("Tom");
与工厂模式区别,没有显式的创建对象,直接将属性和方法赋值给了this对象,没有return语句这种方式调用构造函数经历的4个步骤:
1.创建一个新对象
2.将构造函数的作用域赋给新对象(因此this就指向了这个新对象)
3.执行构造函数中的代码(为这个新对象添加属性)
4.返回新对象
构造函数模式虽然好用但是构造函数模式存在一个主要的问题:每个方法都要在每个实例上重新创建一遍,因此没定义一个函数也就是实例化一个对想。这种方式创建函数会导致不同的作用域链和标识符的解析,但是创建Function新实例的机制仍然是相同的。
5.原型模式
5.1原型模式
function Persion(){
}
Person.prototype.name="Tom";
Person.prototype.sayName=function(){
alert(this.name);
}
var person=new Person();
person.sayName();
这样构造函数变成了空函数,即使如此也还是可以通过调用构造函数创建新对象。但是与构造函数模式不同的是,新对象的属性和方法是由所有的实例共享的。
理解原型对象:
虽然可以通过对象实例访问保存在原型中的值,但是却不能通过对象实例重写原型中的值。当为对象实例添加一个属性时,这个属性就会屏蔽原型对象中保存的同名属性;换句话说添加的这个属性会组织我们访问原型中的那个属性,但是不会修改那个属性
5.2更加简单的原型模式
function Person(){
}
Person.prototype={
name:"Tom",
sayName:function(){alert(this.name)}
}
通过上面的代码,我们把Person.prototype设置为等于一个对象字面量形式的新对象,最终结果相同,但是constructor属性不再指向Person了。所以,要设置constructor的值
function Person(){
}
Person.prototype={
constructor:Person,
name:"Tom",
sayName:function(){alert(this.name)}
}
原型的动态性:由于原型中查找值得过程是一次搜索,因此我们队原型对象的任何修改都能立即从实例上反映出来,即使是先创建了实例后再修改原型也照样如此。
var person=new Person("Tom");
Person.prototype.sayHi=function(){
alert("Hi");
}
person.sayHi();
其原因归根结缔是实例与原型之间的松散连接关系。尽管可以随时为原型添加属性和方法,但是如果重写了整个原型对象,那么情况就不一样了。(用字面量方式重写)
function Person(){
}
var person=new Person()
Person.prototype={
constructor:Person,
name:"Lily",
sayHi:function(){alert(this.name)}
}
person.sayHi();//这样是不正确的
6.动态原型模式
function Person(name){
this.name="Tom";
if(typeof this.sayName!="function"){
Person.prototype.sayName=function(){
alert(this.name);
}
}
}
var person=new Person("Tom");
person.sayName();
这里只有在sayName()方法不存在情况下,才会被添加到原型之中。使用动态原型模式同样不能使用对象字面量重写原型。
7.组合使用构造函数和原型模式