Как избежать конфликта имен при составлении объектов

В JavaScript вы можете создавать объекты, используя extend функция.

Например, у меня может быть observableкласс, который предоставляет набор открытых методов (get,push,set, increment, get, так далее)

В этом случае наблюдаемое также оказывается EventEmitter, поэтому оно также предоставляет дополнительный набор открытых методов (emit,on,removeListener, так далее)

Оба эти класса имеют внутренние префиксные свойства подчеркивания, которые хранят состояние. Eventemitter использует_eventsхранить обработчики событий и наблюдаемое использование_stateа также _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, Это просто уродливо и сводится к вероятности столкновения пространства имен, но не устраняет его.

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 () { ... }
})
Другие вопросы по тегам