TL;博士:
我们需要原型(prototype) OO 中的工厂/构造函数吗?我们可以进行范式转换并完全放弃它们吗?
背景故事:
我最近一直在玩弄 JavaScript 中的 OO 原型(prototype),发现 99% 的 JavaScript 中的 OO 都迫使经典的 OO 模式进入其中。
我对原型(prototype) OO 的看法是它涉及两件事。方法(和静态数据)的静态原型(prototype)和数据绑定(bind)。我们不需要工厂或构造函数。
在 JavaScript 中,这些是包含函数和 Object.create
的对象字面量。 .
这意味着我们可以将一切建模为静态蓝图/原型(prototype)和数据绑定(bind)抽象,最好直接连接到文档样式的数据库中。 IE。对象从数据库中取出并通过使用数据克隆原型(prototype)来创建。这意味着没有构造函数逻辑,没有工厂,没有 new
.
示例代码:
一个伪示例是:
var Entity = Object.create(EventEmitter, {
addComponent: {
value: function _addComponent(component) {
if (this[component.type] !== undefined) {
this.removeComponent(this[component.type]);
}
_.each(_.functions(component), (function _bind(f) {
component[f] = component[f].bind(this);
}).bind(this));
component.bindEvents();
Object.defineProperty(this, component.type, {
value: component,
configurable: true
});
this.emit("component:add", this, component);
}
},
removeComponent: {
value: function _removeComponent(component) {
component = component.type || component;
delete this[component];
this.emit("component:remove", this, component);
}
}
}
var entity = Object.create(Entity, toProperties(jsonStore.get(id)))
次要说明:
特定的代码很冗长,因为 ES5 很冗长。
Entity
上面是一个蓝图/原型(prototype)。任何带有数据的实际对象都可以使用 Object.create(Entity, {...})
创建。 .实际数据(在本例中为组件)直接从 JSON 存储加载并直接注入(inject)
Object.create
称呼。当然,类似的模式适用于创建组件和仅通过 Object.hasOwnProperty
的属性。存储在数据库中。当一个实体第一次被创建时,它是用空的
{}
创建的。实际问题:
现在我的实际问题是
最佳答案
根据您的评论,问题主要是“是否需要构造函数知识?”我觉得是。
一个玩具示例是存储部分数据。在内存中的给定数据集上,当持久化时,我可能只选择存储某些元素(为了效率或数据一致性目的,例如,一旦持久化,这些值本质上是无用的)。让我们以一个 session 来存储用户名和他们点击帮助按钮的次数(因为没有更好的例子)。当我在我的示例中坚持这一点时,我确实没有使用点击次数,因为我现在将它保存在内存中,下次我加载数据时(下次用户登录或连接或其他时)我将初始化值从头开始(大概为 0)。这个特殊的用例是构造函数逻辑的一个很好的候选者。
啊哈,但你总是可以将它嵌入到静态原型(prototype)中:Object.create({name:'Bob', clicks:0});
当然,在这种情况下。但是,如果该值一开始并不总是 0,而是需要计算,该怎么办。嗯,比如说,用户的年龄以秒为单位(假设我们存储了姓名和 DOB)。同样,一个几乎没有用的项目持久化,因为无论如何它都需要在检索时重新计算。那么如何在静态原型(prototype)中存储用户的年龄呢?
显而易见的答案是构造函数/初始化器逻辑。
还有更多的场景,尽管我不觉得这个想法与 js oop 或任何语言特别相关。在我看待计算机系统建模世界的方式中,实体创建逻辑的必要性是内在的。有时我们存储的项目将是一个简单的检索和注入(inject)蓝图,如原型(prototype) shell ,有时值是动态的,需要初始化。
更新
好的,我将尝试一个更真实的例子,为了避免混淆,假设我没有数据库并且不需要保留任何数据。假设我正在制作一个纸牌服务器。每个新游戏都(自然地)是 Game
的一个新实例。原型(prototype)。我很清楚,这里(以及很多)需要他们的初始化逻辑:
例如,我将在每个游戏实例上不仅需要一副静态/硬编码的纸牌,还需要一副随机洗牌的纸牌。如果它是静态的,用户每次都会玩同一个游戏,这显然是不好的。
如果玩家用完,我可能还需要启动一个计时器来完成游戏。同样,不是静态的,因为我的游戏有一些要求:秒数与到目前为止连接的玩家赢得的游戏数量成反比(同样,没有保存的信息,只是这个连接有多少) , 和shuffle的难度成正比(有算法可以根据shuffle的结果判断游戏的难易程度)。
你如何用静态 Object.create()
做到这一点?
关于javascript - JavaScript 中的原型(prototype) OO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6526241/