如何在撰写对象时避免名称冲突

How to avoid name clashes when composing objects

本文关键字:冲突 对象      更新时间:2023-09-26

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

例如,我可能有一个observable类,它公开了一组公共方法(getpushsetincrementget等(。

在这种情况下,可观察量也恰好是一个事件发射器,所以它也公开了一组公共方法(emitonremoveListener等(。

这两个类都具有存储状态的内部下划线前缀属性。事件发射器使用 _events 来存储事件处理程序,可观察对象使用 _state_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已经使用了_state内部属性,并且现在存在名称冲突。

我认为只是"必须知道"哪些对象依赖于混合蛋白安全工作的内部属性是丑陋的。

如何避免混合使用相同内部属性名称的两个对象?

理想情况下,这将使用 ES6 私有名称来解决,但我们还不能这样做,我们无法在不损失性能的情况下模拟它们。除非你能提供一个没有很大性能损失的ES6名称仿真,否则我对这些解决方案不感兴趣。

另一种方法是使用闭包或bind但随后您将为每个实例重新创建函数,这会对性能造成重大影响。另一种选择是将命名空间内部属性作为 __eventEmitter_events__observable_state 。这只是丑陋的,并降低了命名空间冲突的可能性,它不会删除它。

简单的解决方案是"命名空间">

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 () { ... }
})