JavaScript创建对象的几种方式
JavaScript的ES6版本之前的语法中没有class关键字用于创建一个类并通过该类实例化一个对象
ES6版本之前会采用几种方法创建一个对象的类
1. 工厂模式
2. 构造函数模式
3. 改进构造函数模式
4. 原型模式
5. 动态原型模式
6. 寄生构造模式
7. 稳妥构造模式
工厂模式
设计模式中的工厂模式
抽象封装了生成对象的整个过程在工厂中
生成拼装一个对象然后返回给调用者
模式的核心是Object对象的new()方法
优点
解决了JavaScript没有类的问题
createObject()方法能够接受所有构建对象的参数用于创建对象
缺点
没有办法解决对象类型识别的问题
所有的createObject工厂返回的都是Object对象
工厂模式是在Object对象的基础上加以修饰得到新的对象
工厂模式生成对象方法代码:
function createObject (attribute1,attribute2) {
var o = new Object();
o.attribute1 = attribute1;
o.attribute2 = attribute2;
o.function1 = function () {
console.log('Function 1.');
}
return o;
}
对象类型检测代码:
var object1 = createObject('obj','value');
console.log(object1 instanceof createObject); //false
console.log(object1 instanceof Object); //true
构造函数模式
JavaScript允许自定义构造函数
将对象的属性,方法直接加在构造函数的对象上
优点
可以识别对象的类型
缺点
每个MyObject对象实例都会包含MyObject的所有属性和方法
也就是创建了多少个MyObject对象便存在多少Object.function1()方法
重复的方法会很大程度上增加空间的占用
构造函数模式生成对象方法代码:
function MyObject (attribite1,attribute2) {
this.attribute1 = attribite1;
this.attribute2 = attribute2;
this.function1 = function () {
console.log('Function 1.');
}
}
对象类型检测代码:
var myObject = new MyObject('obj','value');
console.log(myObject instanceof MyObject); //true
console.log(myObject instanceof Object); //true
改进构造函数模式
和构造函数模式原理基本相同
不同的是将对象的方法提升到上一层对象之中
在对象中保存的只是对上一层对象中方法的引用
优点
所有的对象共享上一层对象的同一个方法
节省了重复方法对空间的占用
缺点
对象的方法理应只能由对象本身调用
如果将对象的方法定义在上一层对象之中
那么所有作用域内的对象都可以调用此方法
如果对象的方法定义的足够多
那么将严重破坏抽象封装的设计原则
改进构造函数模式生成对象方法代码:
function function1(){
console.log('Function 1.');
}
function MyObject (attribite1,attribute2) {
this.attribute1 = attribite1;
this.attribute2 = attribute2;
this.function1 = function1;
}
测试调用代码:
var myObject = new MyObject('obj','value');
myObject.function1(); //Function 1.
function1(); //Function 1.
原型模式
JavaScript中每个对象都有一个prototype(原型)属性
这个属性是一个指针,指向一个包含该对象实例所有共享属性和方法的对象
可以通过调用对象的构造方法创建对象实例的原型对象
那么对象将包含原型对象上的属性和方法
为对象的属性赋值时,对象上的属性会屏蔽掉原型对象上的属性
优点
所有对象共享原型对象上的属性和方法
原型模式生成对象方法代码:
function MyObject () {
}
MyObject.prototype.attribute1 = 'attribute1';
MyObject.prototype.attribute2 = 'attribute2';
MyObject.prototype.function1 = function () {
console.log('Function1');
}
对象属性屏蔽原型属性代码:
var myobject = new MyObject();
myobject.attribute1 = 'new attribute1';
console.log(myobject.attribute1); //new attribute1