JavaScript创建对象

阅读《JavaScript高级程序设计》6.2 的笔记

工厂模式

1
2
3
4
5
6
7
8
9
10
function createPerson (name, age, job) {
var o = new Object()
o.name = name
o.age = age
o.job = job
o.sayName = function () {
console.log(this.name)
}
return o
}

优点

工厂模式解决了创建多个相似对象的问题(解决创建对象产生大量重复代码)

缺陷

无法识别对象

构造函数模式

1
2
3
4
5
6
7
function Person (name, age) {
this.name = name
this.age = age
this.sayName = function () {
console.log(this.name)
}
}

优点

可以识别对象:

1
2
console.log(person1.constructor == Person)	//	true
console.log(person2.constructor == Person) // true

缺陷

每个方法都要在每个实例上重新创建一遍。我们当然可以将这些方法写到外面作为一个全局函数,然后构造函数中的属性设置等于这个全局函数,但是这样就没有封装性可言了。

原型模式

1
2
3
4
5
6
7
8
9
function Person () {}
Person.prototype.name = 'Yeoman'
Person.prototype.age = '21'
Person.prototype.sayName = function () {
console.log(this.name)
}
const person1 = new Person ()
const person2 = new Person ()
cosnole.log(person1.sayName == person2.sayName) // true

优点

解决了函数共享的问题

缺陷

  1. 省略了为构造函数传递初始化参数这一环节,结果所有实例在默认的情况下都将取得相同的属性值。
  2. 实例化中对象的属性理应是独立的,但是在原型模式这里却被共享了。

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

这是创建自定义类型的最常见的方式。

构造函数模式用于定义实例属性

原型模式用于定义方法和共享属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Person (name, age) {
this.name = name
this.age = age
this.friends = ['a', 'b', 'c']
}

Person.prototype.sayName = function () {
console.log(this.name)
}

const person1 = new Person('yeoman', 21)
const person2 = new Person('lym', 15)

console.log(person1.friends === person2.friends) // false
console.log(person1.sayName === person2.sayName) // true

动态原型模式

把所有信息封装在构造函数中,而通过在构造函数中初始化原型(仅在必要的情况下),又保持了同时使用构造函数和原型的优点。

1
2
3
4
5
6
7
8
9
10
function Person (name, age) {
this.name = name
this.age = age
this.friends = ['a', 'b', 'c']
if ('function' != typeof this.sayName) {
Person.prototype.sayName = function () {
console.log(this.name)
}
}
}

寄生构造函数模式

可以看做工厂模式和构造函数模式的结合体。

其基本思想就是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象。

1
2
3
4
5
6
7
8
9
function Person (name, age) {
var o = new Object()
o.name = name
o.age = age
o.sayName = function () {
console.log(this.name)
}
return o
}

返回的对象与构造函数或者与构造函数的原型属性之间没有什么关系,也就是说,构造函数返回的对象与构造函数外部创建的对象没有什么区别。为此,不能依赖 instanceof 操作符来确定对象的类型。

稳妥构造函数模式

稳妥对象适合在一些安全的环境中(这些环境中会禁止使用this和new),或者防止数据被其他应用程序(如Mashup程序)改动时使用。稳妥构造函数遵循与寄生构造函数类似的模式,但是有两点不同:一是新创建对象的实例方法不引用this,二是不使用new操作符调用构造函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function Person(name , age , job){
// 创建要返回的对象
var o = new Object();

// 可以在这里定义私有的变量和函数

// 添加方法
o.sayName = function(){
alert(name); // 不使用this.name
};

// 返回对象
return o;
}

var friend = Person('nicholas', 29 , 'software engineer'); // 不使用new
friend.sayName(); // 'nicholas'
文章作者: Yeoman Li
文章链接: https://yeomanli.github.io/2019/05/10/JavaScript创建对象/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Yeoman's Blog