2016-11-14 5 views
0

Редактировать: Причина, по которой я выполняю описанный ниже процесс, заключается в том, что я могу хранить ссылку на getter/setter в словаре. Это позволяет мне иметь ключ моего словаря как идентификатор элемента HTML. Таким образом, если свойство изменяется в HTML, я могу сделать что-то вроде:Хранение/установщик класса Javascript ES6, когда наследование включено.

var propData = allMyGetterSetters[e.originalTarget.id]; 
propData.getSet.set(propData.obj, e.originalTarget.value); 

Это также позволяет мне сделать петлю и обновить все HTML, должны изменить его моя логика.


Мне нужно сохранить ссылку на геттер/сеттеры нескольких свойств одного из классов. Я сумел сделать это с помощью следующего кода:

Object.getOwnPropertyDescriptor(Object.getPrototypeOf(myClassObj.position), "x"); 

Для простоты, так как я должен делать это несколько раз, у меня есть следующий метод:

_makeGetSetObj(object, property){ 
    return { 
     getSet: Object.getOwnPropertyDescriptor(Object.getPrototypeOf(object), property), 
     obj: object 
    }; 
} 

И последующий код будет выглядеть например:

var xPos = this._makeGetSetObj(myClassObj.position, "x"); 
// ... 
xPos.getSet.get(xPos.obj); 

Все это отлично работает.

Однако теперь мне нужно сохранить ссылку на геттер/сеттер моего объекта myclassObj. Однако, следующее не работает

this._makeGetSetObj(myClassObj, "name"); 

Это на самом деле дает мне ошибку, что name не существует на объекте. Я сумел понять, что проблема моя наследственность, которая выглядит примерно так

|-- BaseClass 
    |-- MyClass 
    |-- DerivedClass 

Проблема, кажется, что myClassObj на самом деле является объектом типа DerivedClass, который не обладает свойством name на Это.

Так что, если я это сделать:

this._makeGetSetObj(myClassObj.__proto__, "name"); 

Он работает, чтобы получить прототип, но когда я пытаюсь использовать его, как показано выше (с моей xPos например), он терпит неудачу, потому что кажется, все еще сохраняя ссылку в obj как объект DerivedClass.

Если я тяну за пределами моего метода, и попробовать вещи вручную, это работает:

var name = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(myClassObj.__proto__), "name"); 
name.get(myClassObj); 

Это явно нарушает мой метод, хотя, как одна часть требует __proto__ в то время как другая часть нет.

Итак, мой вопрос: есть ли способ сохранить мою текущую логику или мне нужно создать специальный метод для мест с описанной проблемой?

Спасибо.

+0

Что означает «хранить ручку для геттеров/сеттеров»? Какую проблему ты пытаешься решить? – jfriend00

+0

@ jfriend00 Только то, что я показываю в фрагментах кода. Возможно, «ссылка» была бы лучшим словом? – David

+0

Кажется, что это работает. Попробуйте эту скрипту https://jsfiddle.net/pcrfuuc9/ –

ответ

2

Жесткий код прототипа не пахнет хорошо.всегда должны быть итерация Прототип цепи:

let proto = obj; 
let descriptor; 
do { 
    descriptor = Object.getOwnPropertyDescriptor(proto, prop); 
} while (!descriptor && proto = Object.getPrototypeOf(proto)) 
... 

Эта функциональность была уже реализована на Reflect. Вместо анализ дескрипторов вручную, это может быть

const getSet = { 
    get:() => Reflect.get(obj, prop), 
    set: (val) => { Reflect.set(obj, prop, val) } 
}; 

Или ... просто

const getSet = { 
    get:() => obj[prop], 
    set: (val) => { obj[prop] = val } 
}; 

Потому что это то, что происходит, когда аксессоры вызываются напрямую.

+0

Ничего себе, это намного чище, чем то, что я делал! Теперь меня немного раздражает, что я не нашел ничего об использовании 'Reflect', когда я исследовал, как это сделать. В качестве побочного примечания причина, по которой я не повторяюсь, заключается в том, что я не хочу всех свойств. Некоторые из них предназначены только для использования в коде. – David

+1

Да, у нас это в ES6. Неясно, почему существует необходимость использовать такой «словарь», но следует заметить, что сохранение ссылок на произвольные вещи из DOM является прямым способом утечки памяти. – estus

+0

Причина для словаря заключается в том, что я могу иметь событие в поле ввода, которое сообщит мне, когда значение изменится, и что новое значение может быть просмотрено и изменено. Который, помимо чистого кода, также позволяет мне изменить то, что подключено к системе, изменив только два места (1. Добавьте поле HTML, 2. Добавьте строку, которая позволяет JS искать ее и получать/устанавливать значение). – David