1. 工厂模式
function createCar (manufacturer, brand, type) {
let o = new Object()
o.manufacturer= manufacturer
o.brand = brand
o.type = type
o.run = function () {
console.log(this.manufacturer)
}
return o
}
let car1 = createCar('上汽', '大众', '朗逸')
let car2 = createCar('广汽', '现代', '菲斯塔')
工厂模式可以解决创建多个相似对象问题,但是无法解决对象识别问题(怎能知道一个对象的类型)
2.构造函数模式
function Car (manufacturer, brand, type) {
this.manufacturer = manufacturer
this.brand = brand
this.type = type
this.run = function () {
console.log(this.manufacturer)
}
}
let car1 = new Car('上汽', '大众', '朗逸')
let car2 = new Car('广汽', '现代', '菲斯塔')
构造函数模式可以将构造函数的实例标识为一种特定类型car1和car2分别保存着Car的一个不同实例
使用构造函数的主要问题,就是每个方法都要在每个实例上重新创建一遍。
// 我们也可以将构造函数的方法转移到构造函数之外
function Car (manufacturer, brand, type) {
this.manufacturer = manufacturer
...,
this.run = run
}
function fun () {
console.log(this.manufacturer)
}
将构造函数的方法转移到构造函数之外,创建了许多全局作用域的变量,而这些全局的变量可能只会被某个对象调用,容易造成全局污染。
3.原型模式
function Car (){}
Car.prototype.manufacturer= '上汽'
Car.prototype.brand = '大众'
Car.prototype.run = function () {
consloe.log(this.manufacturer)
}
let car1 = new Car()
let car2 = new Car()
console.log(car1.run == car2.run) // true
无需将属性,方法定义在构造函数,可将属性,方法直接添加到原型对象中,这些属性,方法可以由特定类型的所有实例共享。
// 更简单的原型语法
function Car () {}
Car.prototype = {
manufacturer: '上汽',
brand: '大众',
...,
run: function () {
console.log(this.manufacturer)
}
}
let car1 = new Car()
简单原型语法重写了默认的prototype对象,因此constructor属性不再指向Car。
// constructor属性不再指向Car
console.log(car1.constructor == Car) // false
// 改进
function Car () {}
Car.prototype = {
constructor: Car,
manufacturer: '广汽',
brand: '大众',
...,
run: function () {
console.log(this.name)
}
}
原型模式省略了构造函数初始化参数的环节,结果导致所有实例都能取到相同值。
同时,共享属性和方法也会有一个问题,主要是针对引用类型值的属性,会修改所有使用本应用类型的值。
function Car () {}
Car.prototype = {
constructor: Car,
manufacturer: '广汽',
tyre: ['橡胶', '碳纤维'],
...,
run: function () {}
}
let car1 = new Car()
let car2 = new Car()
car1.tyre.push('钢材')
console.log(car1.tyre === car2.tyre) // true (本不想需要取值相等)
4.组合(构造函数模式和原型模式)
// 推荐使用的模式
function Car (manufacturer, brand, type) {
this.manufacturer = manufacturer
this.brand = brand
this.type = type
this.tyre = ['橡胶', '碳纤维']
}
Car.prototype = {
constructor: Car,
run: function () {
console.log(this.manufacturer)
}
}
let car1 = new Car('上汽', '大众', '朗逸')
let car2 = new Car('广汽', '现代', '菲斯塔')
car1.tyre.push('钢材')
console.log(car1.tyre === car2.tyre) // false
每个实例都有自己的实例属性副本,同时共享方法的引用,最大限度节省内存。