要在JavaScript中创建一个对象,最简单的是直接使用字面量来创建,可是这么做在对象较多时会产生大量重复的代码,由此引发了创建对象模式的产生。这些模式就是用来产生对象的。
批量产生js对象
function createPerson(name) {
var o = new Object();
o.name = name;
o.sayName = function() {
return this.name;
};
return o;
}
var person = createPerson("foo");
利用这个函数调用一次产生一个对象,确实很方便。
可是问题在哪呢,属性每个对象一个可以接受,可是方法每个对象也都一个太重复了。因为js中函数也是对象,不像Java会将方法放到静态方法区。js是将函数作为对象的一部分一起存储的。这太浪费了。
看一下例子
function Person(name) {
this.name = name;
this.sayName = function() {
return this.name;
};
}
var person = new Person("foo");
构造函数模式同样存在和工厂模式一样的问题。从本质上讲构造函数就是一种工厂模式。只不过一些共有的步骤都默认执行了(创建对象,返回对象)。
那构造函数好在哪呢。好久好在名字上,也可以说是标志。工厂模式产生的全部是Object。而构造函数产生的则有了自己的标志Person,多么霸气的名字。这样不同的构造函数产生的对象不就区分开了嘛。你工厂模式可以吗?
所以可以将构造函数模式看成是工厂模式的升级版,不再是黑工厂!
原型是一个js对象。可以看作是java里的基类。构造方法只是小兵好嘛,真正的幕后主使其实是原型。
原型里面有个方法叫做constructor就是我们说的构造方法。constructor(函数是对象)又有一个属性prototype就是这个原型。
通过构造方法产生的实例都会有内部属性[[Prototype]],就是他们可以知道自己的原型就是那个。感觉就像借腹生子?
原型模式就是把所有的属性和方法都添加到原型上,而构造函数为空。那每个产生的对象肯定也都是空空如也。js在对象中找不到属性或者方法就会去原型中找。
看例子
function Person() {
}
Person.prototype.name = "foo";
Person.protorype.sayName = function() {
return this.name;
}
var person = new Person("foo");
这样我们就可以产生对象了,而且方法只在原型中存在哦,没浪费,但是坏处就是所有的对象共享原型中的属性和方法!
那我们一般肯定是不希望所有的对象共享一个属性,那怎么破呢,构造方法不就可以让每个对象都有自己的属性了吗,由此就产生了组合使用构造函数模式和原型模式。
看个例子就明白
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
return this.name;
}
var person = new Person("foo");
完美,每个对象都有自己的name属性(因为都是用构造函数创建的),又都可以调用原型中的sayName函数。这才是我们想要的对象!
上面的组合使用构造函数和原型模式虽然已经很棒,可是还可以稍稍改进一下。
function Person(name) {
this.name = name;
if (typeof this.sayName !== "function") {
Person.prototype.sayName = function() {
return this.name;
}
}
}
var person = new Person("foo");
如果原型上添加过了就不再添加。本质还是组合使用。
在实际中我们使用这种模式来创建js对象。
感觉这个模式和工厂模式没区别
function Person(name) {
var o = Object();
o.name = name;
o.sayName = function() {
return this.name;
};
return o;
}
var person = new Person("foo");
感觉唯一的不同就是可以通过new 来调用,但是和工厂模式一样不能确定具体是哪个类的实例。感觉没卵用。
function Person(name) {
var o = new Object();
o.sayName = function() {
alert(name); //对name属性操作一番,就是不传出去
};
return o;
}
var person = new Person("foo");
由此创建的对象只能有一种方式操纵name属性,那就是调用sayName方法。这样就安全了,对象只能按照预先设定的方法来操作属性。所以叫稳妥构造函数模式。
以上就是暂时学习到的js创建对象的模式。