Javascript 如何在组合对象时避免名称冲突

Javascript 如何在组合对象时避免名称冲突,javascript,naming-conventions,composition,object-design,Javascript,Naming Conventions,Composition,Object Design,在JavaScript中,您可以使用某种extend函数组合对象 例如,我可能有一个公开一组公共方法的类(get,push,set,increment,get,等等) 在这种情况下,observable也恰好是EventEmitter,因此它还公开了另一组公共方法(emit,on,removeListener,等等) 这两个类都具有存储状态的内部下划线前缀属性。eventemitter使用\u events存储事件处理程序,而observable使用\u state和\u id存储状态和id 现

在JavaScript中,您可以使用某种
extend
函数组合对象

例如,我可能有一个公开一组公共方法的类(
get
push
set
increment
get
,等等)

在这种情况下,observable也恰好是EventEmitter,因此它还公开了另一组公共方法(
emit
on
removeListener
,等等)

这两个类都具有存储状态的内部下划线前缀属性。eventemitter使用
\u events
存储事件处理程序,而observable使用
\u state
\u id
存储状态和id

现在,当我使用对象组合创建一个模型时

var Model = extend({}, Observable, {
    constructor: function () {
        // Oops, I was supposed to know Observable uses the _state name already
        this._state = { ... }
    },
    someMethod: function () { ... }
})
这会导致一个问题,因为
Observable
已经使用了
\u state
内部属性,并且现在存在名称冲突

我认为只有“必须知道”对象依赖于什么样的内部属性才能安全工作。 如何避免在使用相同内部属性名称的两个对象中混合使用?

理想情况下,这可以通过ES6私有名称来解决,但我们还不能做到这一点,我们不能在不损失性能的情况下模仿它们。除非您可以提供一个ES6名称模拟,而该模拟不会造成很大的性能损失,否则我对这些解决方案不感兴趣

另一种方法是使用闭包或
bind
,但随后您将为每个实例重新创建函数,这将导致严重的性能损失。另一种选择是将内部属性命名为
\uuu eventEmitter\u events
\uu observable\u state
。这很难看,降低了名称空间冲突的可能性,但并没有消除它。

简单的解决方案是“名称空间”


如果内存可用,ExtJS通过将EventEmitter实例化为挂起可观察对象的属性,并使用函数绑定将EventEmitter的所有公共方法代理到可观察对象中,同时维护该EventEmitter内的所有私有状态,在对象创建管道中解决该问题。我想编写一个示例,但我要走了……给我一个小时?@zetlen注意,使用函数绑定代理所有公共方法意味着为每个可观察实例创建一大堆新函数。如前所述,这与模拟私有名称一样具有确切的性能损失。这是一个解决方案,但出于性能原因,我们希望避免使用它。我没有注意到您已经提到过,对不起!我不确定你是否断言它有“完全相同”的性能损失。在所有边缘浏览器(也包括IE10)中,都有
Function.prototype.bind
的本机实现。该方法确实返回了一个新函数,但它是否和声明一样昂贵?你告诉我。也许你已经试过了!惩罚是o(n)内存,而不是o(1)。另一个缺点是缺乏可扩展性
var state = "Model@v0.1.3~state";
var Model = extend({}, Observable, {
    constructor: function () {
        // Nice, I used a namespace and don't clash with "Observable@v0.2.3~state"
        this[state] = { ... }
    },
    someMethod: function () { ... }
})