参考:
js 如何创建类(封装)
Class 的基本语法
《JavaScript 设计模式》
JavaScript 类的封装
在 JavaScript 中,类的实现是基于原型继承机制的。如果两个实例都从同一个原型对象上继承了属性,我们说它们是同一个类的实例。
如果两个对象继承自同一个原型,往往意味着它们是由同一个构造函数创建并初始化的。
类的创建
在 JavaScript 中创建一个类很容易,声明一个函数保存在一个变量中,在这个函数内部使用this 添加属性或者方法。

也可以通过在类的原型对象上添加属性和方法。

⁉️ 通过
prototype和this添加属性和方法有什么区别?通过this是在当前对手上添加的,每次对象被创建时这些方法和属性都会被重复创建;而通过prototype继承的方法不是对象自身的,所以当使用这些方法和属性时,会通过prototype一级一级想上查找(原型链),所有不会被重复创建(但是原型上的属性被修改是,所有继承该原型的对象都会被影响)。
⁉️ 什么是
constructor?这是一个属性,当创建一个函数或对象时都会为期创建一个原型对象prototype, 在prototype对象中又会创建一个constructor属性,那么constructor属性指向的就是拥有整个原型对象的函数或者对象。

属性和方法的封装
利用 JavaScript 的函数级作用域,声明在函数内部的变量以及方法在外界是访问不到的,通过此特性即可创建私有变量和私有方法。

思考 new 运算符原理,通过 new 实例化对象时,构造函数执行,this 执行新创建的对象。
类通过 prototype 创建的属性或者方法在类的实例对象是可以通过 this 访问的。

再进一步,利用闭包进行封装
闭包是有权访问另一个函数作用域中变量的函数,即在一个函数内部创建另一个函数。我们将这个闭包作为创建对象的构造函数,在闭包内部返回一个完整的类。
1 | var Book1 = (function() { |
创建对象的安全模式

当忘记写 new 运算符时,是对象的直接复制,对象内部的 this 指向的是全局对象window,使用 instanceof 运算符判断当前 this,在使用闭包的封装中,是不会有整个问题的,其属性和方法都被限定在函数内部的作用域中。
