对象封装的本质

  • 本质很简单,就是构造一个返回一个对象的函数
想想 jQuery 中 api 的构造方式,它就是典型的 “函数返回对象” 式 api

范例代码

//这是构造函数,这里放差异属性
function 士兵(id) {
    this.ID = id        //注:this 不能省
    this.生命值 = 35
}
//这里放公用属性
士兵.prototype = {
    constructor: 士兵,  //注:这里 constructor 属性指向构造函数
    兵种: '德国大兵',
    攻击力: 7,
    行走: function(){},
    奔跑: function(){},
    攻击: function(){}
}
//实例化对象
var 士兵A = new 士兵(1)  //注:new是关键

代码解释

  1. new 的本质

前面我们说过,对象封装就是一个函数返回一个对象,然而代码中,构造函数未见对象也未见 return,这是因为 new 这个语法糖在背后帮我们完成这些事

当我们写 new 的时候,它在构造函数中帮我们多干了几件事

  1. 声明一个空对象
  2. 将 this 指向该对象
  3. 将对象的 proto链到 prototype
  4. 送出该对象

下图是个实验,可以说明 new 帮我们多做了几件事

可以看出,没有 new,this 就是 window,有 new,this 就是准备构造的对象

  1. 封装对象的代码为何一分为二?

很简单,就是为了在大量实例化对象时,节约内存

我们编程中很多对象都是大同小异的

如果不分离,很多重复的属性和方法就要一而再再而三地创建;如果用 prototype 分离出去,构造时只要修改 proto 的引用即可

使用方法是 大同放 prototype 引用,小异放构造函数

需要注意一点是 prototype 往往加一个 constructor,指向构造函数名

总结

对象封装的模板是

function 构造函数() {
    // 差异化属性
    this.xx = a
    this.yy = b
}

// 构造函数.prototype = 一个对象

构造函数.prototype = {
    constructor: 构造函数,
    // 共有属性与方法
    zz: c,
    aa: function() {}
    bb: function() {}
}

var xxxx = new 构造函数()