js

  想起你,内心充满欢喜O(∩_∩)O

对象的创建模式

  • Object构造函数模式

    • 套路: 先创建空Object对象, 再动态添加属性/方法
    • 适用场景: 起始时不确定对象内部数据
    • 问题: 语句太多
    1
    2
    3
    var obj = new Object()
    obj.name = 'Tom'
    obj.setName = function(name){this.name=name}
  • 对象字面量模式

    • 套路: 使用{}创建对象, 同时指定属性/方法
    • 适用场景: 起始时对象内部数据是确定的
    • 问题: 如果创建多个对象, 有重复代码
1
2
3
4
var obj = {
name : 'Tom',
setName : function(name){this.name = name}
}
  • 工厂函数模式
    • 套路: 通过工厂函数动态创建对象并返回
    • 适用场景: 需要创建多个对象
    • 问题: 对象没有一个具体的类型, 都是Object类型
      即通过instanceof判断得到的都是Object类型
      类型不够具体 人和🐶均为同一类型
    • 用的不多 只是比较经典
    • 返回一个对象的函数===>工厂函数 联系真实工厂
1
2
3
4
5
6
7
8
9
10
function createPerson(name, age) { 
var obj = {
name: name,
age: age,
setName: function (name) {
this.name = name
}
}
return obj
}
  • 构造函数模式
    • 套路: 自定义构造函数, 通过new创建实例对象
    • 适用场景: 需要创建多个类型确定的对象
    • 问题: 每个对象都有相同的数据, 浪费内存
1
2
3
4
5
6
function Person(name, age) {
this.name = name;
this.age = age;
this.setName = function(name){this.name=name;};
}
new Person('tom', 12);
  • 组合模式 (构造函数+原型)
    • 套路: 自定义构造函数, 属性在函数中初始化, 方法添加到原型上
    • 适用场景: 需要创建多个类型确定的对象
1
2
3
4
5
6
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.setName = function(name){this.name=name;};
new Person('tom', 12);

继承模式

  • 原型链继承 : 得到方法
1
2
3
4
5
6
7
8
function Parent() {}
Parent.prototype.test = function(){};

function Child() {}
Child.prototype = new Parent(); //子类型的原型指向父类型实例
Child.prototype.constructor = Child //修正constructor属性重新指向子构造函数

var child = new Child(); //有test()
  • 借用构造函数 : 得到属性
    (假继承)
1
2
3
4
5
6
7
function Parent(xxx){this.xxx = xxx}
Parent.prototype.test = function(){};

function Child(xxx,yyy){
Parent.call(this, xxx);//借用构造函数 this.Parent(xxx)
}
var child = new Child('a', 'b'); //child.xxx为'a', 但child没有test()
  • 组合继承 (原型链继承+构造函数)
    • 利用原型链实现对父类型对象的方法继承
    • 利用call()借用父类型构建函数初始化相同属性
1
2
3
4
5
6
7
8
9
10
function Parent(xxx){this.xxx = xxx}
Parent.prototype.test = function(){}

function Child(xxx,yyy){
Parent.call(this, xxx)//借用构造函数 this.Parent(xxx)
}
Child.prototype = new Parent() //得到test()
Child.prototype.constructor = Child //修正constructor属性

var child = new Child(); //child.xxx为'a', 也有test()
  • new一个对象背后做了些什么?
    • 创建一个空对象
    • 给对象设置proto, 值为构造函数对象的prototype属性值 this.proto = Fn.prototype
    • 执行构造函数体(给对象添加属性/方法)

QQ来我QQ撩我哦👇