一、对象创建模式
1.Object构造函数模式
- 先创建空
Object
对象, 再动态添加属性/方法 - 适用场景: 起始时不确定对象内部数据
- 问题: 语句太多
// 先创建空Object对象
var p = new Object()
p.name = 'Tom'
p.age = 12
p.setName = function (name) {
this.name = name
}
2.对象字面量模式
- 使用
{}
创建对象, 同时指定属性/方法 - 适用场景: 起始时对象内部数据是确定的
- 问题: 如果创建多个对象, 有重复代码
var p = {
name: 'Tom',
age: 12,
setName: function (name) {
this.name = name
}
}
var p2 = { //如果创建多个对象代码很重复
name: 'Bob',
age: 13,
setName: function (name) {
this.name = name
}
}
3.工厂模式
- 通过
工厂函数
动态创建对象并返回 - 适用场景: 需要创建多个对象
- 问题: 对象没有一个具体的类型, 都是
Object
类型
function createPerson(name, age) {
var obj = {
name: name,
age: age,
setName: function (name) {
this.name = name
}
}
return obj
}
var p1 = createPerson('Tom', 12)
var p2 = createPerson('Bob', 13)
4.自定义构造函数模式
- 自定义构造函数, 通过
new
创建对象 - 适用场景: 需要创建多个类型确定的对象,与上方工厂模式有所对比
- 问题: 每个对象都有相同的数据, 浪费内存
function Person(name, age) {
this.name = name
this.age = age
this.setName = function (name) {
this.name = name
}
}
var p1 = new Person('Tom', 12)
p1.setName('Jack')
function Student (name, price) {
this.name = name
this.price = price
}
var s = new Student('Bob', 13000)
5.构造函数+原型的组合模式
- 自定义构造函数, 属性在函数中初始化, 方法添加到原型上
- 适用场景: 需要创建多个类型确定的对象
- 放在原型上可以节省空间(只需要加载一遍方法)
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.setName = function (name) {
this.name = name
}
var p1 = new Person('Tom', 23)
var p2 = new Person('Jack', 24)
二、继承模式
1.原型链继承
步骤:
- 定义父类型构造函数
- 给父类型的原型添加方法
- 定义子类型的构造函数
创建父类型的对象赋值给子类型的原型
将子类型原型的构造属性设置为子类型
- 给子类型原型添加方法
- 创建子类型的对象: 可以调用父类型的方法
关键:
子类型的原型为父类型的一个实例对象
//父类型
function Supper() {
this.supProp = '父亲的原型链'
}
//给父类型的原型上增加一个[showSupperProp]方法,打印自身subProp
Supper.prototype.showSupperProp = function () {
console.log(this.supProp)
}
//子类型
function Sub() {
this.subProp = '儿子的原型链'
}
// 子类型的原型为父类型的一个实例对象
Sub.prototype = new Supper()
// 让子类型的原型的constructor指向子类型
// 如果不加,其构造函数找的[`new Supper()`]时从顶层Object继承来的构造函数,指向[`Supper()`]
Sub.prototype.constructor = Sub
//给子类型的原型上增加一个[showSubProp]方法,打印自身subProp
Sub.prototype.showSubProp = function () {
console.log(this.subProp)
}
var sub = new Sub()
sub.showSupperProp() //父亲的原型链
sub.showSubProp() //儿子的原型链
console.log(sub)
2.组合继承
- 利用原型链实现对父类型对象的方法继承
- 在子类型构造函数中使用
call()
,借用父类型构建函数初始化相同属性
function Person(name, age) {
this.name = name
this.age = age
}
function Student(name, age, price) {
//此处利用call(),将 [Student]的this传递给Person构造函数
Person.call(this, name, age)
this.price = price
}
var s = new Student('Tom', 20, 14000)
console.log(s.name, s.age, s.price)