Как избежать конфликта имен при составлении объектов
В 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 () { ... }
})