- 工厂模式
function createPerson(name,age,obj){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName=function(){
alert(this.name);
};
return o;
}
var person1 = createPerson("hello",30,"soft Engineer");
var person2 = createPerson("world",39,"doctor");
主要特点是利用函数来封装以特定接口创建对象。函数每次返回一个包含三个属性一个方法的对象。但同时没有解决对象识别的问题,即怎么知道一个对象的类型。
2. 构造函数模式
构造函数可以用来创建特定类型的对象,同时对于Object和Array原生构造函数也会自动出现在执行环境中,且可以定义自定义对象类型的属性和方法。
function Person(name,age,job){//构造函数始终以大写字母开头,而非构造函数以小写开头
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person1=new Person("hello",29,"soft Engineer");
var person2=new Person("world",30,"doctor");
相对于person1和person2都分别保存着Person的不同的实例,且两个对象都有一个constructor属性,该属性指向Person。同时构造函数也是函数,可以不通过new操作符来调用,那函数的this对象总是指向global对象。同时也可以采用call或者apply()来调用Person()函数。
主要缺点:每个方法都要在每个实例中重新创建一遍。都要在堆区开辟空间,会导致不同的作用域链和标识符解析。因此,可以将函数转移到构造函数外部。
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = sayName;
}
function sayName(){//全局属性
alert(this.name);
};
var person1=new Person("hello",29,"soft Engineer");
var person2=new Person("world",30,"doctor");
这种方法的缺点就是当对象需要定义多个方法就会创建多个全局函数,于是自定义应用类型毫无封装可言。
3. 原型模式
每个函数都有一个prototype属性。prototype是个指针,指向一个对象,对象的用途即包含可以由特定类型的所有实例共享的属性和方法。使用原型对象的好处就是可以让所有对象实例共享它所包含的所有属性和方法。普通的对象只有_proto _属性。
function Person(){
}
Person.prototype.name = "hello";
Person.prototype.age = 29;
this.job = "Software Engineer";
Person.prototype.sayName = function(){//全局属性
alert(this.name);
};
var person1=new Person();
person1.sayName() //"hello"
var person2=new Person();
虽然还是调用构造函数来创建新对象的方法,且新对象还会有相同的属性和方法,但与构造模式不同的是,新对象所有属性和方法都是由实例共享的。
关于原型对象:创建个新函数,会为该函数创建一个prototype属性,这个属性指向函数的原型对象,所有原型对象都会自动获得一个contructor属性,这个属性指向一个contructor属性,这个属性包含prototype所在函数的指针,而通过这个构造函数可以继续添加属性和方法。同时调用构造函数创建新实例后,内部都会包含指针,指向构造函数的原型属性。这正是多个对象实例之间共享原型所保存的属性和方法的基本原理。
同时通过isPrototypeOf()可以来确定对象之间是否会存在这种关系。判断内部是否有指向原型的指针。当在实例中添加一个属性时,则会屏蔽原型对象中保存的同名属性,通过delete操作符可以删除实例属性重新访问原型属性。hasOwnprototype()可以检测一个属性是否在实例中或者是原型中。
关于原型对象的动态性—实例与原型之间的松散连接关系:
function Person(){
}
var friend=new Person();
Person.prototype={
constructor:Person,
name:"Nicloas",
age:30,
sayName:function(){
alert(this.name);
}
};
friend.sayName() //error
调用构造函数会为实例添加一个指向原型对象的[[prototype]]属性,而把原型修改为另外一个对象则等于切断了构造函数与最初原型的关系。实例中的指针是指向原型,而不是指向构造函数。
4. 组合使用构造函数和原型模式
主要思想:构造函数用于定义实例属性,原型模式用于定义方法和共享的属性。且应用最广泛。
function Person(name,age,job){ //构造函数模式
this.name = name;
this.age = age;
this.job=job;
this.friends=["hello","joe"];
}
Person.prototype={ //原型模式
constructor:Person,
sayName:function(){
alert(this.name);
}
};
var person1 = new Person("helo",20,"doctor");
var person2 = new Person("hol",29,"engineer");
主要特点:使用构造函数创建的实例不会共享,通过原型模式创建的会共享。
5. 动态原型模式
即通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型。
function Person(name,age,job){ //构造函数模式
this.name = name;
this.age = age;
this.job=job;
this.friends=["hello","joe"];
if(typeOf this.sayName!="function"){
Person.prototype.sayName=function(){{ //原型模式
alert(this.name);
}
};
}
var person1 = new Person("helo",20,"doctor");
person.sayName();
6. 寄生构造函数模式
基本思想:就是创建一个函数,函数作用仅为封装创建对象的代码,然后返回新创建的对象。
function Person(name,age,job){ //构造函数模式
var o=new Object();
o.name = name;
o.age = age;
o.job = job;
o.friends = ["hello","joe"];
o.sayName = function(){ //原型模式
alert(this.name);
};
return o;
}
var person1 = new Person("helo",20,"doctor");
person.sayName();
构造函数返回的对象与构造函数的原型属性无任何关系。
7. 稳妥构造函数模式
委托对象,指的是没有公共属性,而且其方法也不引用this的对象。与寄生构造函数不同的是,一是不使用new调用构造函数,二是构造的实例对象不使用this。
function Person(name,age,job){ //构造函数模式
var o=new Object();
o.friends = ["hello","joe"];
o.sayName = function(){ //原型模式
alert(name);
};
return o;
}
var person1 = Person("helo",20,"doctor");
person.sayName();
以上均摘自于Javascript高级程序设计。。