备注:这里对于用字面量形式和Object构造函数就不做过多的声明
工厂模式
function createPerson (name,age,sex) {
var o = new Object();
o.name = name;
o.age = age;
o.sex = sex;
return o;
}
var person1 = createPerson('sam',20,'man');
这种方式本质上其实就是对Object构造函数多加了一层封装
构造函数模式
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
this.say = function(){
return 'say hello'
}
}
//创建
var person = new Person('sam',20,'man')
使用构造函数的缺点是每创建一次实例,函数内部的方法都会重新构建一次,对于私有方法来说这是可行的,但对于一些公用的实现相同功能的方法频繁去实例化是没有必要的。
原型模式
function Person(){};
Person.prototype.name = 'name';
Person.prototype.age = 'age';
Person.prototype.job = ['student','teacher'];
var person = new Person();
原型模式的问题是所有实例共享属性和方法,对于只是添加一个原型上存在的同名属性而言,是会隐藏原型上的属性,这个时候的影响不会特别大。但是对于引用类型的数据,如果只是在修改数据,就会带来比较大的影响。比如:
var person1 = new Person();
var person2 = new Person();
person1.job.push('leader');
//person1.job: 'student','teacher','leader
//person2.job: 'student','teacher','leader'
如上所示,在person1的实例上我们修改了job数组,此时打印出的person2的job也发生了改变,这可能并不是我们所希望看到的。通常来说我们都希望每个实例都有自己的属性定义,这个时候单纯使用原型模式就不是很适合。
使用构造函数模式和原型模式的组合
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype.getName = function(){
return 'hello' + this.name;
}
var person = new Person('sam',20,'sex');
person.getName(); // hello sam