字面量模式
在使用JavaScript进行代码书写时,创建对象的方式中首先推荐的模式就是字面量方式进行创建。
const person = {
name: 'jade',
age: 5
}
存在的问题:
如果仅仅是创建单个对象,使用字面量是时间简单方便的,但是创建很对同类型对象时,这种方式就会产生大量重复代码。
工厂模式
工厂模式是一种被广泛熟知的设计模式,该模式将创建对象的过程抽象成工厂函数,用函数封装创建对象的具体细节。
function crator(name, age) {
const person = {};
person.namge = name;
person.age = age;
return person;
}
存在的问题:
工厂模式可以解决创建同类型对象的问题,但是也引入了新的问题,使用工厂函数使得创建对象的过程被隐藏,对象创建完成以后就很难知道对象的具体类型,存在对象识别的问题。
构造函数模式
JavaScript
中构造函数可用来创建特定类型的对象,Object
、Array
等是原生的构造函数,在运行执行环境时就存在,我们也可以自定义构造函数。
function Person(name, age) {
this.namge = name;
this.age = age;
this.walk = function() {
console.log(`${this.name} can walk!`);
}
}
const person = new Person('Jam', 27);
构造函数与普通函数基本没有区别,主要是使用方式不同,构造函数主要是使用new操作符进行调用,返回同是Person
类型的对象。对象的constructor
是对象类型标识,但在进行对象类型识别时instanceof
更可靠。
存在的问题:
构造函数存在最大的问题就是方法不能共享,例如walk
方法所有的Person
类型的对象都具有,但是该方法要被每一个对象实例化一次,造成不必要的开销和内存。
原型模式
JavaScript
函数有一个prototype
属性,指向一个对象引用,该对象上保存了特定类型对象共享的所有的属性和方法。
function Person(name, age) {
}
Person.prototype.namge = 'Jam';
Person.prototype.walk = function() {
console.log(`${this.name} can walk!`);
}
const person = new Person();
存在的问题:
原型模式也不是完美无缺的,其最大的问题就是由于共享性所造成的,因为实例的__proro__
属性与构造函数的prototype
属性是松散的关系,仅是一个指针引用,因此在构造函数的prototype
修改属性和方法会立刻反应到所有的实例上。
组合(构造函数和原型)模式
使用构造函数定义实例属性,使用原型定义共享的属性和方法。这种组合模式目前是定义引用类型的默认模式,其集合了构造函数模式和原型模式的优势。
function Person(name) {
this.name = name;
}
Person.prototype.walk = function() {
console.log(`${this.name} can walk!`);
}