前几天整理了有关JavaScript创建对象的几种方式,今天就一并的从印象笔记中整理上来。


工厂模式

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('jayant', 23, 'web')
var person2 = createPerson('esss', 22, '**')

// 因为方法中已经new了一个object了,所以我们不需要new它


构造函数模式

1
2
3
4
5
6
7
8
9
10
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
this.sayName = function () {
alert (this.name)
}
}
var person1 = new Person('jayant', 23, 'web')
var person2 = new Person('esss', 22, 'no')

构造函数Person与工厂模式createPerson的区别:

  • 没有显式创建对象,内部new Object
  • 直接将属性赋予this对象
  • 没有return 语句

如果需要使用构造函数生成一个Person实例,则我们需要new一下,new一个对象会经历以下过程:

  • 创建一个新对象
  • 将构造函数作用域赋予新对象,也就是this
  • 执行构造函数中的代码
  • 返回新对象

构造函数的不足之处

person1与person2中每个实例都有一个这个方法,都需要创建一遍,造成内存上的浪费

1
2
3
4
this.sayName = function () {
alert(this.name)
}
alert(person1.sayName == person2.sayName)  //false

于是又根据此不足之处衍生出以下方法:

构造函数的优化:

1
2
3
4
5
6
7
8
9
10
function Person (name, age, job) {
this.name = name
this.age = age
this.job = job
this.sayName = sayName
}
// 1、将共有方法定义在全局上,2、函数多的话,要定义多
function sayName() {
alert(this.name)
}

但是这个操作又会造成如果函数很多,需要定义很多方法;并且是定义成为了全局函数,这完全不需要


原型模式

每个函数都有一个prototype属性,是一个指针,为了使所有实例可以共享到属性和方法,从而不必在构造函数中定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Person() {
}
// 定义在原型上
Person.prototype.name = 'Jayant'
Person.prototype.age = 23
Person.prototype.job = 'web'
Person.prototype.sayName = function() {
alert(this.name)
}
var person1 = new Person()
person1.sayName() //Jayant

var person2 = new Person()
person2.sayName() //Jayant

好处: 公共方法,属性可以共用,同时是定义在其构造函数原型上的

不足: 是过于共享,以至于所有的实例都拥有相同的方法,实例了

例如:

1
2
person1.age = 100
person2.age // 100


组合使用构造函数模式与原型模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function Person(name, age) {
this.name = name
this.age = age
this.friends = ['乾隆', '康熙']
}
Person.prototype = {
constructor: Person
sayName: function () {
alert(this.name)
}
}
var person1 = new Person()
var person2 = new Person()
person1.friends.push('嬴政')
person1.friends //乾隆,康熙,嬴政
person2.friends //乾隆,康熙

//认可度,使用最广泛的一种创建对象方式


寄生构造函数模式

1
2
3
4
5
6
7
8
9
10
11
function Person(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 friend = new Person('Jayant', 23, 'web')

工厂模式

1
2
3
4
5
6
7
8
9
10
11
function Person(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 friend = Person('Jayant', 23, 'web')

寄生构造函数与工厂模式的区别

1
2
3
4
// 寄生构造函数
var friend = new Person('Jayant', 23, 'web')
// 工厂模式
var friend = Person('Jayant', 23, 'web')


稳妥构造函数模式

1
2
3
4
5
6
7
8
9
10
11
function Person (name, age) {
var o = new Object()
o.sayName = function () {
alert(name)
}
return name
}
var person = Person('jayant', 23)
person.sayName() //jayant

// 除了调用sayName方法,没办法获取其数据成员,某种情况下安全性 up up