js创建对象的方法

1、创建 Object 实例

1
2
3
4
5
var person = new Object();
person.name = "Adele";
person.age = 29;
person.job = "FE";
person.sayName = funtion () { alert(this.name); }

2、对象字面量

1
2
3
4
5
6
var person = {
name: "Adele",
age: 29,
job: "FE"
sayName: funtion () { alert(this.name); }
}

1和2有个明显缺点:使用同一个接口创建很多对象,会产生大量重复代码

3、工厂模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function createPerson (name,age,job) {
var o=new Object();
o.name=name;
o.age=age;
o.job=job;
o.sayName=function(){
alert(this.name);
}
return o;
}
var person1=createPerson ("DJL1",22,"student1");
var person2=createPerson ("DJL2",22,"student2");
alert(typeof createPerson ("DJL2",22,"student2"));//object
alert(person1 instanceof createPerson);//这肯定是false啦

工厂模式虽然解决了创建多个相似对象这个问题,但却没有解决对象识别问题(即怎样知道一个对象的类型)。

注:instanceof运算符用于验证原型对象与实例对象之间的关系

4、构造函数模式

1
2
3
4
5
6
7
8
9
10
11
12
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 ("DJL1",22,"student1");
var person2=new Person ("DJL2",22,"student2");
alert(person1 instanceof Person);//true

Person与上文不同的地方在于:

  • 没有显式创建对象
  • 直接将属性和方法赋给了this对象
  • 没有return语句

要创建Person的新实例必须使用new操作符,这种方式调用构造函数实际上会经历以下四个步骤:

  1. 创建一个新对象
  2. 将构造函数的作用域赋给新对象(也就是说,构造函数中的this指向这个新对象,或者说赋给这个新对象)
  3. 执行构造函数中的代码(也就是说,为新对象添加属性和方法)
  4. 返回新对象

对象的constructor属性用来标识对象类型,但是,提到检测对象类型,还是instanceof更可靠一些。

主要问题:每个方法都要在每个实例上重新创建一遍。即每个实例的Function实例都不同。

5.原型模式

我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,此对象包含所有实例共享的属性和方法。因此,可以将所有实例共享它包含的属性和方法。换句话说,不必在构造函数中定义对象实例的信息,而是将这些信息直接添加到原型对象中。

6.组合使用构造函数模式和原型模式

构造函数模式:定义实例属性;
原型模式:定义方法和共享属性;

7.动态原型模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Person(name, age, job) {
// 属性
this.name = name;
this.age = age;
this.job = job;
// 方法
if (typeof this.sayName != 'function') {
// 这段代码只执行了一次
Person.prototype.sayName = function() {
alert(thia.name);
}
}
}

8.寄生构造函数模式

1
2
3
4
5
6
7
8
9
10
11
12
function Person(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = funtion () {
alert(this.name);
}
return o;
}
var friend = new Person("Adele", "29", "FE");
friend.sayName(); // Adele

寄生构造函数模式和工厂模式没有本质区别,通过new 操作符的就叫寄生构造函数模式,直接调用的就叫工厂模式。

9.稳妥构造函数模式

稳妥对象指的是,没有公共属性,而且其方法也不引用this的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function Person(name, age, job) {
// 创建要返回的对象
var o = new Object();
// private members
var nameUC = name.toUpperCase();
// public members
o.sayName = function() {
alert(name);
};
o.sayNameUC = function() {
alert(nameUC);
};
return o;
}
var friend = Person("Adele", 29, "FE");
friend.sayName(); // Adele
friend.sayNameUC(); // ADELE
alert(friend.name); // undefined
alert(friend.nameUC); // undefined

凡是想设为 private 的成员都不要挂到 Person 返回的对象 o 的属性上面,挂上了就是 public 的了。当然,这里的 private 和 public 都是从形式上类比其他 OO 语言来说的,其实现原理还是 js 中作用域、闭包和对象那一套。感觉实现得挺巧妙的。

稳妥对象最适合在一些安全环境中(这些环境会禁用this和new)使用,或者在防止数据被其他应用程序改动时使用。