1.工厂模式
- 工厂模式抽象了创建对象的过程,用函数来封装以特定接口创建对象的细节
1 function createPerson(name, age, job) { 2 var o = new Object(); 3 o.name = name; 4 o.age = age; 5 o.job = job; 6 o.sayName = function () { 7 console.log(this.name); 8 } 9 return o; 10 } 11 12 var person1 = createPerson('Nick', 20, 'worker'); 13 var person2 = createPerson('Greg', 30, 'Doctor');
- 函数createPerson()能根据接受的参数来构建一个包含必要信息的Person对象,虽然解决了创建多个相似对象的问题,但没有解决对象识别的问题(即怎么样知道一个对象的类型)。
2.构造函数模式
- 使用 new 操作符创建对象,所创建的对象既是Object的实例,同时也是Person的实例。
1 function Person(name, age, job) { 2 this.name = name; 3 this.age = age; 4 this.job = job; 5 this.sayName = function () { 6 console.log(this.name); 7 } 8 } 9 10 var person1 = new Person('Nick', 20, 'worker'); 11 var person2 = new Person('Greg', 30, 'Doctor');
- 但是这种方式的缺点,是每个方法都要在每个实例上重新创建一遍,创建两个具有相投功能的函数没有意义。以下是优化后的代码:
1 function Person(name, age, job) { 2 this.name = name; 3 this.age = age; 4 this.job = job; 5 this.sayName = sayName; 6 } 7 8 function sayName() { 9 console.log(this.name); 10 } 11 12 var person1 = new Person('Nick', 20, 'worker'); 13 var person2 = new Person('Greg', 30, 'Doctor'); 14 15 person2.sayName();
- 这种方式将sayName()方法放到全局作用域,但是没有体现封装性。
3.原型模式
- 原型模式创建对象的好处是可以让所有的实例共享属性和方法,而不必在实例的时候重复创建
1 function Person() { 2 } 3 4 Person.prototype = { 5 constructor: Person, 6 name: "Nick", 7 age: 29, 8 job: "Worker", 9 sayName: function () { 10 console.log(this.name); 11 } 12 } 13 14 var person1 = new Person(); 15 person1.sayName();
- 但是这种方法所有实例共享原型里的属性,当其中一个实例改变属性,会导致全局更改。
4.组合使用构造函数模式和原型模式
- 既可以自定义传参,而且还共享方法,是用来定义引用类型的一种默认形式。
1 function Person(name, age, job) { 2 this.name = name; 3 this.age = age; 4 this.job = job; 5 } 6 7 Person.prototype = { 8 constructor: Person, 9 sayName: function () { 10 console.log(this.name); 11 } 12 } 13 14 var person1 = new Person("Nick", 29, 'Worker'); 15 person1.sayName();
5.动态原型模式
- 将所有构造函数和原型封装到一个构造函数中,通过检查某个应该存在的方式是否有效来决定是否需要初始化原型。
1 function Person(name, age, job) { 2 this.name = name; 3 this.age = age; 4 this.job = job; 5 if(typeof this.sayName != 'function'){ 6 Person.prototype.sayName = function(){ 7 console.log(this.name); 8 } 9 } 10 } 11 12 var person1 = new Person("Nick", 29, 'Worker'); 13 person1.sayName();
6.寄生构造模式
- 在前几种模式不适用的情况下,可以使用寄生构造模式。模式的思想是构造一个函数,该函数仅仅封装创建对象的代码,再返回新创建的对象。
1 function Person(name, age, job) { 2 var o = new Object(); 3 o.name = name; 4 o.age = age; 5 o.job = job; 6 o.sayName = function () { 7 console.log(this.name); 8 } 9 return o; 10 } 11 12 var person1 = new Person("Nick", 29, 'Worker'); 13 person1.sayName();
- * 除了特殊情况,最好不要使用
7.稳妥构造函数模式
- 没有公共属性,而且其他的方法不引用this对象,适合在一些安全性相对要求高的环境下使用
1 function Person(name, age, job) { 2 var o = new Object(); 3 /** 4 * 这里定义私有属性 5 */ 6 o.sayName = function () { 7 console.log(name); 8 } 9 return o; 10 } 11 12 var person1 = Person("Nick", 29, 'Worker'); 13 person1.sayName();