JS创建对象的方法

先讲一下工厂模式吧:

创建一个对象,然后给这个对象新建属性和方法。
var box = new Object();//创建一个 Object 对象
box.name = 'Lee';//创建一个 name 属性并赋值
box.age = 100;//创建一个 age 属性并赋值
box.run = function () {//创建一个 run()方法并返回值
  return this.name + this.age + '运行中...';
};
alert(box.run());//输出属性和方法的值

上面创建了一个对象,并且创建属性和方法,在 run()方法里的 this,就是代表 box 对象本身。这种是 JavaScript 创建对象最基本的方法,但有个缺点,想创建一个类似的对象,就会产生大量的代码。
var box2 = box;//得到 box 的引用
box2.name = 'Jack';//直接改变了 name 属性
alert(box2.run()); //用 box.run()
发现 name 也改变了
var box2 = new Object();
box2.name = 'Jack';
box2.age = 200;
box2.run = function () {
  return this.name + this.age + '运行中...';
};
alert(box2.run());//这样才避免和 box 混淆,从而保持独立 
为了解决多个类似对象声明的问题,我们可以使用一种叫做工厂模式的方法,这种方法就是为了解决实例化对象产生大量重复的问题。
 function createObject(name, age) {//集中实例化的函数
var obj = new Object();
obj.name = name;
obj.age = age;
obj.run = function () {
  return this.name + this.age + '运行中...';
};
return obj;
}
var box1 = createObject('Lee', 100);
var box2 = createObject('Jack', 200);
alert(box1.run()); alert(box2.run()); //第一个实例 //第二个实例 //保持独立

工厂模式解决了重复实例化的问题,但还有一个问题,那就是识别问题,因为根本无法搞清楚他们到底是哪个对象的实例。
alert(typeof box1);//Object
alert(box1 instanceof Object);//true

ECMAScript 中可以采用构造函数(构造方法)可用来创建特定的对象。类型于 Object 对象。
function Box(name, age) {//构造函数模式
this.name = name;
this.age = age;
this.run = function () {
   return this.name + this.age + '运行中...';
};
}
var box1 = new Box('Lee', 100);
var box2 = new Box('Jack', 200); //new Box()
alert(box1.run());
alert(box1 instanceof Box); //很清晰的识别他从属于 Box
使用构造函数的方法,即解决了重复实例化的问题,又解决了对象识别的问题,但问题是,这里并没有 new Object(),为什么可以实例化 Box(),这个是哪里来的呢?使用了构造函数的方法,和使用工厂模式的方法他们不同之处如下:
1.构造函数方法没有显示的创建对象(new Object());
2.直接将属性和方法赋值给 this 对象;
3.没有 renturn 语句。

来源:http://www.cnblogs.com/asqq/archive/2013/02/01/3194993.html

再来说一下总的:

工厂模式:

function createPerson(name,age,job){ 
var o = {}; 
o.name = name; 
o.age = age; 
o.job = job; 
o.sayName = function(){ 
alert(this.name); 
}; 
return o; 
} 
var tanya = createPerson("tanya","30","female"); 
var ansel = createPerson("ansel","30","male"); 
tanya.sayName(); 
ansel.sayName(); 
function createPerson(name,age,job){ 
var o = { 
name : name, 
age : age, 
job : job, 
sayName : function(){ 
alert(this.name); 
} 
}; 
return o; 
} 
var tanya = createPerson("tanya","30","female"); 
var ansel = createPerson("ansel","30","male"); 
tanya.sayName(); 
ansel.sayName(); 

构造函数模式(利用强大的this)

function Person(name,age,job){ 
this.name = name; 
this.age = age; 
this.job = job; 
this.sayName = function(){ 
alert(this.name); 
}; 
} 
var tanya = new Person("tanya","30","female"); 
var ansel = new Person("ansel","30","male"); 
tanya.sayName(); 
ansel.sayName(); 
function Person(name,age,job){ 
this.name = name; 
this.age = age; 
this.job = job; 
this.sayName = function(){ 
alert(this.name); 
}; 
} 
Person("tanya","30","female"); 
Person("ansel","30","male"); 
window.sayName(); 
window.sayName(); 

发现两次弹出的都是ansel,这是因为不用new的话,就不是一个person的实例,而仅仅在执行函数。而在全局作用域调用一个函数时this总是指向Global对象。而Global对象在浏览器中就是window对象。 

apply和call模式

function Person(name,age,job){ 
this.name = name; 
this.age = age; 
this.job = job; 
this.sayName = function(){ 
alert(this.name); 
}; 
} 
var olivia = {}; 
Person.call(olivia,"tanya","30","female"); 
olivia.sayName(); 
var philip = {} 
Person.apply(philip,["ansel","30","male"]); 
philip.sayName(); 

原型模式:

原型模式就要考虑原型链了,分析一下,sayName方法在实例中被重复定义了两次,但其实没有必要创造两个一样的副本。使用原型方法,可以使是tanya和ansel的共享一个sayName方法。 
于是原型模式的写法如下:

function Person(name,age,job){ 
this.name = name; 
this.age = age; 
this.job = job; 
} 
Person.prototype.sayName= function(){ 
alert(this.name); 
}; 
var tanya = new Person("tanya","30","female"); 
var ansel = new Person("ansel","30","male"); 
tanya.sayName(); 
ansel.sayName(); 

实际应用时,不是一成不变的套用某种模式,活学活用。需要共享方法的时候就用原型模式,需要使用副本的时候就用构造模式,还可以结合起来,把所有信息都封装在构造函数中,而通过在构造函数中初始化原型,使得对象保持了同时使用构造函数和原型的优点。 

function Person(name,age,job){ 
this.name = name; 
this.age = age; 
this.job = job; 
if (typeof sayName != "function" ){ 
Person.prototype.sayName= function(){ 
alert(this.name); 
}; 
} 
} 
var tanya = new Person("tanya","30","female"); 
var ansel = new Person("ansel","30","male"); 
ansel.sayName = function () { 
alert("Hi ansel, how hansome you are!"); 
} 
tanya.sayName(); 
ansel.sayName(); 

 

来源:http://www.jb51.net/article/16366.htm

 

补充:http://www.zcfy.cc/article/513

 

posted @ 2016-09-08 18:41  chenxj  阅读(184)  评论(0)    收藏  举报