Как присвоить переменной свойство, а не его значение?
Товарищи, вот то, что я смог сделать:
<div id='Elem'>Lorem</div> И код: var elem = document.getElementById('Elem'); var current = null; Object.defineProperty(Element.prototype,'text',{ get(){ current = this.textContent; console.log(current); return '??????' // возвращаем сеттер свойства 'text' для данного объекта (в данном случае для элемента) } }) // Пример желаемого синтаксиса: var txt = elem.text; console.log(txt); // 'Lorem' txt = 'Ipsum'; // 'Lorem -> Ipsum' txt = 'Dolor'; // 'Ipsum -> Dolor' txt.free(); // 'variable 'txt' is free now' Что должен вернуть геттер, чтобы я потом мог присваивать новый текст элементу 'elem', согласно приведенному синтаксису. Предположу что объект или функцию, но ведь, наверное, не существует сеттера самого объекта. Возможно Javascript не может возвращать свойство, а лишь его значение. Бывают ли безымянные свойства? Хрен знает )) Приведенный синтаксис позволит упростить и сократить код. Иначе будет: elem.text = 'Ipsum'; elem.text = 'Dolor'; elem.text = 'Sit Amet' //...Дублирование кода ( повторение 'elem.text' сто раз ) (( Тут мы каждый раз получаем свойство для того чтобы поменять его значение. Мне же нужно ОДИН РАЗ получить свойство, а затем сетить(задавать) его значение, пока не надоест Я же предлагаю просто присваивать переменной новое значение и то (нап. функция), что следит за этой переменной будет менять содержимое 'elem' согласно присвоенному значению. То есть мы как бы привязываем переменную под нужное СВОЙСТВО до тех пор пока не введем: somevar.free() Возможно ли это? Что должен вернуть геттер, чтобы реализовать указанный синтаксис? |
Teamur,
возможно не window а Element.prototype, это так на всякий. |
рони,
спасибо что заметили, это я опечатался, конечно Element.prototype, но! Дальше все равно не знаю что делать. |
Teamur,
тоже не знаю как сократить elem.text до txt |
рони,
Если я в геттере свойства 'text' верну текст элемента: return this.textContent , то у меня в переменной 'txt' будет храниться строка, и всё - тупик. И как бы я ни старался присваивая строке другую строку, в данном случае 'Ipsum', содержимое элемента не изменится. Геттер должен вернуть СВОЙСТВО, а не его значение, чтобы я смог задать новое значение. Вот в чем суть вопроса. Спасибо |
function getSetter(obj, prop) { return function (value) { obj[prop] = value; }; } var example = { text: 'Hello'}; var setExampleText = getSetter(example, 'text'); console.log(example ); // {text: "Hello"} setExampleText('Hello World'); console.log(example ); //{text: "Hello World"} |
Сеттер нужен наверное...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style>html{font:2em sans-serif;}</style> </head> <body> <div id="lorem"></div> <script> function createSetter(element, variable, context) { Object.defineProperty(context || self, variable, { set: function(value) { console.log(value); let x = Symbol.for("textContentPromise"); let promise = element[x] || Promise.resolve(); element[x] = promise.then(() => { return new Promise(resolve => { setTimeout(() => resolve(element.textContent = value), 200); }); }); } }); } createSetter(lorem, "text"); text = "lorem"; text = "ipsum"; text = "dolor"; text = "sit"; text = "amet"; text = "Rise"; text = "как"; text = "видишь"; text = "заметно"; text = "и"; text = "на"; text = "обычном"; text = "компе"; text = "lorem"; text = "ipsum"; text = "dolor"; text = "sit"; text = "amet"; </script> </body> </html> |
Такой тупизм (см. ниже цепочку), я могу легко сократить до Было-стало, сразу задав конечное значение, НО!
txt='Ipsum', txt='Dolor', txt='Sit Amet' такая непрерывная Цепочка была записана для понимания идеи. На самом деле между этими строками может быть любой другой код! Все это придумано для того, чтобы я по ходу написания функции не дублировался сто раз, получая каждый раз свойство заново. Я подумал, что было бы круто, например, в начале функции получить требуемое свойство, в данном случае 'text', и использовать его много раз, не дублируя код! Реальный код будет конечно не таким, как тупизм выше, например: function Handler(){ let txt = elem.text; console.log('Поехали'); txt = 'Ipsum'; // * let div = document.createElement('div'); div.dataset.type = 'toolbar'; elem.after(div); txt = 'Dolor'; // * div.append('Приехали'); txt = 'Sit Amet' // * } Как видим между строками со звездочкой есть другой код! )) Поэтому нужна привязка к свойству, а не значению. |
Мне же просто нужно один раз сохранить в переменной свойство,
чтобы не получать его каждый раз заново. Не понимаю почему зашла речь о синхронности и тп. Это максимум, что я могу вам показать, чтобы поддержать тему: Node.prototype.bind = function(varName, propName) { let elem = this; Object.defineProperty(window,varName,{ get() { console.log('-> '+elem[propName]); varName = elem[propName]; }, set(newVal) { elem[propName] = newVal; console.log(elem[propName]+' -> '+newVal); varName = elem[propName] } }); this.free = function() { // Тут что-то напутал ( varName = null; console.log('var '+varName+' is FREE now!'); } } <div id='Elem'>Lorem</div> Юзаж: let elem = document.getElementById('Elem'); elem.bind('txt','textContent'); console.log(txt); // -> Lorem if (elem.style.color == '#000') { txt = 'Ipsum'; // Lorem -> Ipsum } else { txt = 'Dolor'; // Ipsum -> Dolor }; txt.free(); // var txt is FREE now! console.log(txt) // null Надеюсь на вашу помощь, спасибо! |
Rise,
Отлично! Блин, зря я написал условный оператор, забудем о нём. Он мне нахрен не нужен )). Опять же я хотел показать, что между сеттингом нового значения может быть что угодно. |
Rise,
у ТС изначально один вопрос можно вытащить сеттер да/нет, если да то как? |
Что нужно сделать, чтобы реализовать именно такой синтаксис? :
var txt = Elem.textContent; alert(txt) // 'Lorem'; // ... код в 50 строк ... txt = 'Ipsum'; // 'Lorem -> Ipsum' // ... еще код в 1000 строк ... txt = 'Dolor'; // 'Ipsum -> Dolor' Может нужно слушать window, и когда происходит обращение к переменной txt, изменять содержимое элемента. Изначально я хотел это реализоавть используя Object.observe(), но его как назло забросили ( Можно ли как-то сразу начать отслеживание объекта window при загрузке страницы? Похоже этот синтаксис нереален в Javascript |
Rise,
Что угодно, кроме действий, которые сделают Elem не доступным в переменной txt. Кроме того, переменную txt нужно жестко привязать именно к Elem. И запретить присвоение переменной чего-либо, кроме СТРОКИ. |
Хотя бы теоретически можно реализовать синтаксис в посте #16?
Для меня главный вопрос сейчас не в том будет ли виснуть мой браузер, на моей тестовой страничке, а можно ли реализовать синтаксис? |
Может нужно слушать window, и когда происходит обращение к переменной txt, изменять содержимое элемента.
Почему бы для этого не подошёл сеттер, определённый у объекта window? //там, где у Вас в посте №16, строка 1, я предлагаю заменить на: Object.defineProperty(self, "txt", { set: function(value) { Elem.textContent = value; } }); Не знаю, по какой причине игнорируете такой способ, хотя с производительностью у него всё в порядке. Ещё один способ... window = new Proxy(window, { set: function(object, property, value) { object[property] = value; if(property === "txt") { Elem.textContent = value; } } }); ...который на самом деле не работает! Вы хотите сделать txt = "lorem";, но переменной присвоен не сам сеттер, а то что он возвратил. Даже если там был бы сеттер, присвоив переменной новое значение, вы бы его просто переопределили, поскольку это функция. Кстати почему вместо переменной txt не использовать функцию txt... И тогда вместо txt = `lorem`; будет просто txt `lorem`;. Ещё меньше символов... Изменённый код из поста №16 var txt = function(value) { return "0" in arguments ? Elem.textContent = value : Elem.textContent; }; alert(txt()) // 'Lorem'; // ... код в 50 строк ... txt `Ipsum`; // 'Lorem -> Ipsum' // ... еще код в 1000 строк ... txt `Dolor`; // 'Ipsum -> Dolor' |
Malleys,
спасибо! По поводу txt`Ipsum` Тоже думал об этом, но как бы традиционно и естественнее присваивать значение через знак равенства. txt - это, конечно, хорошо, но вдруг мне понадобится получить текст другого элемента и придумать для него новую переменную, нап. "note". Мне придется сделать еще одну функцию для ее обработки, хотя в Javascript можно создать класс для этого и наследовать поведение. |
Цитата:
Node.prototype.bind = function (variable, property, type) { var node = this; Object.defineProperty(window, variable, { get: function () { return node[property]; }, set: function (value) { if (typeof value == type) node[property] = value; }, configurable: true }); }; // ... elem.bind('txt', 'textContent', 'string'); // ... txt = 'Ipsum'; // ... txt = 'Dolor'; // ... delete txt; // txt is not defined |
Rise,
супер, наконец-то что-то похожее, я ковырялся с этой задачей недели две! спасибо, мужики! |
Если на волне вдохновения будут еще какие-то идеи реализации, пожалуйста напишите и их.
Тема от этого только выиграет и будет интереснее и весомее! |
Часовой пояс GMT +3, время: 15:38. |