Javascript 创建对象的七种方法

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();
原文地址:https://www.cnblogs.com/gemicat/p/4810921.html