1.对象创建模式

方式一: Object构造函数模式

  • 套路: 先创建空Object对象, 再动态添加属性/方法
  • 适用场景: 起始时不确定对象内部数据
  • 问题: 语句太多
  1. /*
  2. 一个人: name:"Tom", age: 12
  3. */
  4. // 先创建空Object对象
  5. var p = new Object()
  6. p = {} //此时内部数据是不确定的
  7. // 再动态添加属性/方法
  8. p.name = 'Tom'
  9. p.age = 12
  10. p.setName = function (name) {
  11. this.name = name
  12. }
  13. //测试
  14. console.log(p.name, p.age)
  15. p.setName('Bob')
  16. console.log(p.name, p.age)

方式二: 对象字面量模式

  • 套路: 使用{}创建对象, 同时指定属性/方法
  • 适用场景: 起始时对象内部数据是确定的
  • 问题: 如果创建多个对象, 有重复代码
  1. var p = {
  2. name: 'Tom',
  3. age: 12,
  4. setName: function (name) {
  5. this.name = name
  6. }
  7. }
  8. //测试
  9. console.log(p.name, p.age)
  10. p.setName('JACK')
  11. console.log(p.name, p.age)
  12. var p2 = { //如果创建多个对象代码很重复
  13. name: 'Bob',
  14. age: 13,
  15. setName: function (name) {
  16. this.name = name
  17. }
  18. }

方式三: 工厂模式

  • 套路: 通过工厂函数动态创建对象并返回
  • 适用场景: 需要创建多个对象
  • 问题: 对象没有一个具体的类型, 都是Object类型
  1. function createPerson(name, age) { //返回一个对象的函数===>工厂函数
  2. var obj = {
  3. name: name,
  4. age: age,
  5. setName: function (name) {
  6. this.name = name
  7. }
  8. }
  9. return obj
  10. }
  11. // 创建2个人
  12. var p1 = createPerson('Tom', 12)
  13. var p2 = createPerson('Bob', 13)
  14. // p1/p2是Object类型
  15. function createStudent(name, price) {
  16. var obj = {
  17. name: name,
  18. price: price
  19. }
  20. return obj
  21. }
  22. var s = createStudent('张三', 12000)
  23. // s也是Object

方式四: 自定义构造函数模式

  • 套路: 自定义构造函数, 通过new创建对象
  • 适用场景: 需要创建多个类型确定的对象
  • 问题: 每个对象都有相同的数据, 浪费内存
  1. //定义类型
  2. function Person(name, age) {
  3. this.name = name
  4. this.age = age
  5. this.setName = function (name) {
  6. this.name = name
  7. }
  8. }
  9. var p1 = new Person('Tom', 12)
  10. p1.setName('Jack')
  11. console.log(p1.name, p1.age)
  12. console.log(p1 instanceof Person)
  13. function Student (name, price) {
  14. this.name = name
  15. this.price = price
  16. }
  17. var s = new Student('Bob', 13000)
  18. console.log(s instanceof Student)
  19. var p2 = new Person('JACK', 23)
  20. console.log(p1, p2)

方式五: 构造函数+原型的组合模式

  • 套路: 自定义构造函数, 属性在函数中初始化, 方法添加到原型上
  • 适用场景: 需要创建多个类型确定的对象
  1. function Person(name, age) { //在构造函数中只初始化一般函数
  2. this.name = name
  3. this.age = age
  4. }
  5. Person.prototype.setName = function (name) {
  6. this.name = name
  7. }
  8. var p1 = new Person('Tom', 23)
  9. var p2 = new Person('Jack', 24)
  10. console.log(p1, p2)

2.继承模式

方式1: 原型链继承

  1. 1. 套路
  2. 1. 定义父类型构造函数
  3. 2. 给父类型的原型添加方法
  4. 3. 定义子类型的构造函数
  5. 4. 创建父类型的对象赋值给子类型的原型
  6. 5. 将子类型原型的构造属性设置为子类型
  7. 6. 给子类型原型添加方法
  8. 7. 创建子类型的对象: 可以调用父类型的方法
  9. 2. 关键
  10. 1. 子类型的原型为父类型的一个实例对象
  1. //父类型
  2. function Supper() {
  3. this.supProp = 'Supper property'
  4. }
  5. Supper.prototype.showSupperProp = function () {
  6. console.log(this.supProp)
  7. }
  8. //子类型
  9. function Sub() {
  10. this.subProp = 'Sub property'
  11. }
  12. // 子类型的原型为父类型的一个实例对象
  13. Sub.prototype = new Supper()
  14. // 让子类型的原型的constructor指向子类型
  15. Sub.prototype.constructor = Sub
  16. Sub.prototype.showSubProp = function () {
  17. console.log(this.subProp)
  18. }
  19. var sub = new Sub()
  20. sub.showSupperProp()
  21. // sub.toString()
  22. sub.showSubProp()
  23. console.log(sub) // Sub

方式2: 借用构造函数继承(假的)

  1. 套路:
  2. 定义父类型构造函数
  3. 定义子类型构造函数
  4. 在子类型构造函数中调用父类型构造
  5. 关键:
  6. 在子类型构造函数中通用call()调用父类型构造函数
  1. function Person(name, age) {
  2. this.name = name
  3. this.age = age
  4. }
  5. function Student(name, age, price) {
  6. Person.call(this, name, age) // 相当于: this.Person(name, age)
  7. /*this.name = name
  8. this.age = age*/
  9. this.price = price
  10. }
  11. var s = new Student('Tom', 20, 14000)
  12. console.log(s.name, s.age, s.price)

方式3: 原型链+借用构造函数的组合继承

  1. 利用原型链实现对父类型对象的方法继承
  2. 利用super()借用父类型构建函数初始化相同属性
  1. function Person(name, age) {
  2. this.name = name
  3. this.age = age
  4. }
  5. Person.prototype.setName = function (name) {
  6. this.name = name
  7. }
  8. function Student(name, age, price) {
  9. Person.call(this, name, age) // 为了得到属性
  10. this.price = price
  11. }
  12. Student.prototype = new Person() // 为了能看到父类型的方法
  13. Student.prototype.constructor = Student //修正constructor属性
  14. Student.prototype.setPrice = function (price) {
  15. this.price = price
  16. }
  17. var s = new Student('Tom', 24, 15000)
  18. s.setName('Bob')
  19. s.setPrice(16000)
  20. console.log(s.name, s.age, s.price)