Home >  > 构造函数和工厂函数

构造函数和工厂函数

0

一、创建对象的几种方式

1、各自独立声明模式

var box1 = new Object();	//声明第一个对象并给各属性赋值
box1.name = 'Lee';
box1.age = 100;
box1.run = function () {
	return this.name + this.age + '运行中...';
};
alert(box.run());

var box2 = new Object();	//声明第二个对象并给属性赋值
box2.name = 'Jack';
box2.age = 200;
box2.run = function () {
	return this.name + this.age + '运行中...';
};
alert(box2.run());

此时box2和box1是相互独立的,不会混淆。
但是这样子每声明一个结构相同的对象,都得加一段代码,特别不方便,所以有了下面的工厂模式。

2、工厂模式:

这样子每次new对象时只需调用createObject()方法即可,同时,还可以传参初始化对象。
但由于new出来的对象都从属于Object,当我要使new出来的对象在本质做一些区分的时候,就不行了,此时就有了更简便的构造函数模式。

3、构造函数

使用构造函数,即解决了需要重复实例化的问题,又解决了对象识别的问题,是最常用的new对象的模式。

注意:
此处box1.run != box2.run, 因为他们判断的是引用地址,由此可知,两个对象的方法分别存储在不同的地方,是两个不同的方法。
但 box1.run() == box2.run(),因为它们返回值一样。
当有了对象以后,自然而然就会涉及到对象属性及方法的共享问题。
构造函数模式创建出的对象说白了还是相互独立的(比如上面的box1.run != box2.run),如果我要在两个对象之间共享某些属性的话,就必须要采用原型prototype了。

二、通过原型创建对象

1、原型模式

function Box() {} //声明一个构造函数
Box.prototype.name = 'Lee'; //在原型里添加属性
Box.prototype.age = 100;
Box.prototype.arr = ['aaa','bbb'];
Box.prototype.run = function () { //在原型里添加方法
	return this.name + this.age + '运行中...';
};
var box1 = new Box();
var box2 = new Box();

//修改普通属性,看下会不会影响prototype
alert(box1.name);	//Lee
box1.name = 'Rinima';
alert(box1.name);	//Rinima
alert(box2.name);	//Lee,修改box1的普通属性,相当于直接在box1中添加一个属性,是不会牵扯到原型中的属性的。
					//这一点非常好。但是如果是引用对象(数组)的话,就有问题了。

//修改引用属性,看下会不会影响prototype
alert(box1.arr);	//aaa,bbb
box1.arr.push('ccc');
alert(box1.arr);	//aaa,bbb,ccc
alert(box2.arr);	//aaa,bbb,ccc,修改box1的引用属性,却牵扯到了原型中的属性。
			//这是因为arr只是个引用地址,指向数组真实存储的位置,修改box1中的引用属性就是修改引用所指向的数组,所以原型也被修改了
			//这是我们不希望看到的!

该模式的优点:
1、所new出来的对象在prototype中的属性是共享的,此时box1.run == box2.run
2、能保证所new的对象实例的属性完全统一(和缺点2相对)
该模式的缺点:
1、当含有引用类型的属性时,引用类型所指向的属性是存在prototype中,直接在对象中修改引用属性就把所有对象的引用属性都修改了
2、该种模式省略了初始化传参,使得new出来的所有属性都是一样的

暧昧帖

本文暂无标签

发表评论

*

*