一起来学Javascript 设计模式 之 构造器模式

364 阅读2分钟

构造器模式

这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战

在面向对象编程中,构造器是一个当新建对象的内存被分配后,用来初始化该对象的一个特殊函数。 对象构造器是被用来创建特殊类型的对象,首先它要准备使用的对象,其次在对象初次被创建时,通过接收参数,构造器要用来对成员的属性和方法进行赋值的。

基础构造器

在这个构造器内部,关键字 this 引用到刚被创建的对象。

// 构造函数
function Car(model, year, miles) {
  this.model = model;
  this.year = year;
  this.miles = miles;

  this.toString = function () {
    return `${this.model} has done ${this.miles} miles`;
  };
}

const civic = new Car('Honda Civic', 2009, 20000);
const mondeo = new Car('Ford Mondeo', 2010, 5000);

console.log(civic.toString()); // "Honda Civic has done 20000 miles"
console.log(mondeo.toString()); // "Ford Mondeo has done 5000 miles"

上面这个是简单版本的构造器模式,但它还是有些问题。一个是难以继承,另一个是每个Car构造函数创建的对象中,toString()之类的函数都被重新定义。这个非常不好,理想的情况是所有 Car 类型的对象都应该引用同一个函数。 使用“原型”的构造器 在 JavaScript 中每个函数都有一个prototype的属性。当我们调用 JavaScript 的构造器创建一个对象时,构造函数prototype上的属性对于所创建的对象来说都可见。这样就可以创建多个Car的实例对象,而共用一个prototype方法了。

// 构造函数
function Car(model, year, miles) {
  this.model = model;
  this.year = year;
  this.miles = miles;
}

Car.prototype.toString = function () {
  return `${this.model} has done ${this.miles} miles`;
};

const civic = new Car('Honda Civic', 2009, 20000);
const mondeo = new Car('Ford Mondeo', 2010, 5000);

console.log(civic.toString()); // "Honda Civic has done 20000 miles"
console.log(mondeo.toString()); // "Ford Mondeo has done 5000 miles"

通过上面代码,单个toString()实例被所有的Car对象所共享了。 顺便来看看 ES6 的 class 类写法。

class Car {
  constructor(model, year, miles) {
    this.model = model;
    this.year = year;
    this.miles = miles;
  }

  toString() {
    return `${this.model} has done ${this.miles} miles`;
  }
}

const civic = new Car('Honda Civic', 2009, 20000);
const mondeo = new Car('Ford Mondeo', 2010, 5000);

console.log(civic.toString()); // "Honda Civic has done 20000 miles"
console.log(mondeo.toString()); // "Ford Mondeo has done 5000 miles"