你写过JavaScript的类吗?你知道JavaScript的类的机制是什么样的吗?

在相当长的一段时间里, JavaScript 只有一些近似类的语法元素(比如 new 和 instanceof), 不过在后来的 ES6 中新增了一些元素, 比如 class 关键字。这是不是意味着 JavaScript 中实际上有类呢? 简单来说: 不是。

由于类是一种设计模式, 所以你可以用一些方法近似实现类的功能。为了满足对于类设计模式的最普遍需求, JavaScript 提供了一些近似类的语法。虽然有近似类的语法, 但是 JavaScript 的机制似乎一直在阻止你使用类设计模式。 在近似类的表象之下, JavaScript 的机制其实和类完全不同。 语法糖和(广泛使用的)JavaScript“类” 库试图掩盖这个现实, 但是你迟早会面对它: 其他语言中的类和 JavaScript 中的“类” 并不一样。

你写过JavaScript的类吗?你知道JavaScript的类的机制是什么样的吗?

在许多面向类的语言中,“标准库” 会提供 Stack 类, 它是一种“栈” 数据结构(支持压入、 弹出, 等等)。 Stack 类内部会有一些变量来存储数据, 同时会提供一些公有的可访问行为(“方法”), 从而让你的代码可以和(隐藏的) 数据进行交互(比如添加、 删除数据)。

但是在这些语言中, 你实际上并不是直接操作 Stack(除非创建一个静态类成员引用, 这超出了我们的讨论范围)。 Stack 类仅仅是一个抽象的表示, 它描述了所有“栈” 需要做的事, 但是它本身并不是一个“栈”。 你必须先实例化 Stack 类然后才能对它进行操作。

1、类的构造

“类” 和“实例” 的概念来源于房屋建造。建筑师会规划出一个建筑的所有特性: 多宽、 多高、 多少个窗户以及窗户的位置, 甚至连建造墙和房顶需要的材料都要计划好。 在这个阶段他并不需要关心建筑会被建在哪, 也不需要关心会建造多少个这样的建筑。建筑师也不太关心建筑里的内容——家具、 壁纸、 吊扇等——他只关心需要用什么结构来容纳它们。建筑蓝图只是建筑计划, 它们并不是真正的建筑, 我们还需要一个建筑工人来建造建筑。建筑工人会按照蓝图建造建筑。 实际上, 他会把规划好的特性从蓝图中复制到现实世界的建筑中。完成后, 建筑就成为了蓝图的物理实例, 本质上就是对蓝图的复制。 之后建筑工人就可以到下一个地方, 把所有工作都重复一遍, 再创建一份副本。

建筑和蓝图之间的关系是间接的。 你可以通过蓝图了解建筑的结构, 只观察建筑本身是无法获得这些信息的。 但是如果你想打开一扇门, 那就必须接触真实的建筑才行——蓝图只能表示门应该在哪, 但并不是真正的门。

一个类就是一张蓝图。 为了获得真正可以交互的对象, 我们必须按照类来建造(也可以说实例化) 一个东西, 这个东西通常被称为实例, 有需要的话, 我们可以直接在实例上调用方法并访问其所有公有数据属性。这个对象就是类中描述的所有特性的一份副本。你走进一栋建筑时, 它的蓝图不太可能挂在墙上(尽管这个蓝图可能会保存在公共档案馆中)。 类似地, 你通常也不会使用一个实例对象来直接访问并操作它的类, 不过至少可以判断出这个实例对象来自哪个类。

把类和实例对象之间的关系看作是直接关系而不是间接关系通常更有助于理解。 类通过复制操作被实例化为对象形式:

你写过JavaScript的类吗?你知道JavaScript的类的机制是什么样的吗?

如你所见, 箭头的方向是从左向右、 从上向下, 它表示概念和物理意义上发生的复制操作。

2、类的构造函数

类实例是由一个特殊的类方法构造的, 这个方法名通常和类名相同, 被称为构造函数。 这

个方法的任务就是初始化实例需要的所有信息(状态)。举例来说, 思考下面这个关于类的伪代码(编造出来的语法) :

你写过JavaScript的类吗?你知道JavaScript的类的机制是什么样的吗?

我们可以调用类构造函数来生成一个 CoolGuy 实例:

Joe = new CoolGuy( "jumping rope" )

Joe.showOff() // 这是我的绝技: 跳绳

注意, CoolGuy 类有一个 CoolGuy() 构造函数, 执行 new CoolGuy() 时实际上调用的就是它。 构造函数会返回一个对象(也就是类的一个实例), 之后我们可以在这个对象上调用showOff() 方法, 来输出指定 CoolGuy 的特长。

类构造函数属于类, 而且通常和类同名。 此外, 构造函数大多需要用 new 来调, 这样语言引擎才知道你想要构造一个新的类实例。

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin
avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: