构造器模式
这是我参与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"