5

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

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

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

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

Я считаю уродливым просто «знать», какие объекты полагаются на то, какие внутренние свойства для mixin безопасно работают.

Как избежать смешивания в двух объектах, которые используют одно и то же имя внутреннего свойства?

В идеале это будет решаться с помощью частных имен ES6, но мы пока не можем этого сделать, и мы не можем имитировать их без потери производительности. Если вы не можете обеспечить эмуляцию имен ES6, то не имеет большого штрафа за производительность. Меня не интересуют эти решения.

Альтернативой может быть использование замыканий или bind, но тогда вы будете воссоздавать функции для каждого экземпляра с существенным штрафом за производительность. Другой альтернативой было бы внутренние свойства пространства имен как __eventEmitter_events и __observable_state. Это просто уродливо и сводится к вероятности столкновения пространства имен, он не удаляет его.

+0

хороший вопрос ..! – Alnitak

+0

Если память используется, ExtJS решает ее в конвейере создания объекта, создавая экземпляр EventEmitter как свойство, зависающее от Observable, и проксирование всех * общедоступных * методов EventEmitter в Observable с помощью связывания функций, сохраняя при этом все личное состояние внутри этого EventEmitter , Я бы привел пример, но я собираюсь АФК ... дай мне час? – zetlen

+0

@zetlen отмечают, что проксирование всех общедоступных методов с использованием привязки функций означает создание целого ряда новых функций для каждого наблюдаемого экземпляра. как уже упоминалось, это точная оценка производительности как эмуляция частных имен. Это решение, но мы хотим избежать его по соображениям производительности. – Raynos

ответ

0

тривиальное решение "Пространства имен"

var state = "[email protected]~state"; 
var Model = extend({}, Observable, { 
    constructor: function() { 
     // Nice, I used a namespace and don't clash with "[email protected]~state" 
     this[state] = { ... } 
    }, 
    someMethod: function() { ... } 
}) 
Смежные вопросы