Добавление объекта с методами к конструктору
Приветствую!
Можно ли после создания конструктора добавить к нему объект с методами, использующими методы этого конструктора? function CreateTest(name) { this.name = name; this.roll = () => ["simple", "hard"][Math.round(Math.random())]; /* // объявление объекта внутри конструктора работает this.renameObj = { rename: function() { return this.name = `${this.roll()} ${this.name}`; }.bind(this) }; */ } /* // добавление объекта после объявления конструктора не работает CreateTest.renameObj = { rename: function() { return this.name = `${this.roll()} ${this.name}`; }.bind(CreateTest) }; */ let test = new CreateTest("js test"); test.renameObj.rename(); |
В javascript прототипное наследование.
Все методы добавляются в любое время в CreateTest.prototype. |
Так тоже не работает
CreateTest.prototype.renameObj = { rename: function() { return this.name = `${this.roll()} ${this.name}`; }.bind(CreateTest) }; Выдает ошибку "this.roll is not a function". |
Ты ищешь свойство у объекта созданного функцией а добавляешь свойство самой функции которая тоже ведет себя как объект.
Естественно объект созданный функцией и функция создающая объект это разные объекты и свойства у них разные |
Забавная задачка, ибо каждый объект в js независим, и никак обратно не связан со своим "родителем". Тут надо подумать, как сделать по-красивее.(но лучше вообще так не делать:))
|
А как же свойство Obj.__proto__.constructor ?
|
Думаю, надо объяснить, откуда вообще взялась эта задача. Я пишу библиотеку для работы с анимациями. В ее основе конструктор, содержащий свойства - координаты передаваемого в качестве аргумента DOM элемента, часть методов предназначена для работы с этими свойствами, а остальные методы - это методы-обертки, необходимые для вызова пользовательских функций (упакованных вместе с их параметрами в объекты). Т.е. пользователь может написать простую функцию, меняющую координаты элемента по некой формуле, поместив ее со своими параметрами в объект, затем вызвать ее через функцию обертку с промисом и raf. При этом он абстрагируется от асинхронной логики и думает только над уравнением перемещения. Чтобы это осуществить, как раз и требуется добавить объект в конструктор (тоже через обертку, чтобы это мог делать пользователь-новичок, не знакомый с ООП в js).
|
MallSerg, под "родителем" я имел ввиду не конструктор, а тот объект в котором он лежит. Наверно надо было сказать "никак не связан со своим контейнером"?)
|
Aetae,
То же не совсем понятно Есть родитель на которого всегда ссылка obj.prototype Есть функция создающая объект на которую указывает ссылка Obj.__proto__.constructor Есть this который динамически заменяется и всегда указывает в контексте какого объекта он исполняется. <script> function GetName() { return this.name; } var vasa = {name: "Вася"}; var lena = {name: "Лена"}; var petia = {name: "Петя"}; vasa.gn = GetName; lena.gn = GetName; petia.gn = GetName; document.write ( vasa.gn() + "<br>") ; document.write ( lena.gn() + "<br>") ; document.write ( petia.gn() + "<br>") ; </script> R2R, Без конкретного тестового примера понять что то сложно возможно использование наследования поможет небольшой пример <script> function CreateTest (){ this.__proto__ = CreateTest; this.x = 5; this.y = 20; } var ele = new CreateTest(); CreateTest.newFunc = function ( par){ alert ( this.x + this.y + par ); } ; ele.newFunc ("----"); </script> |
MallSerg, он хочет примерно такую наркоманию:
function CreateTest(name) { this.name = name; this.roll = () => ["simple", "hard"][Math.round(Math.random())]; /* // объявление объекта внутри конструктора работает this.renameObj = { rename: function() { return this.name = `${this.roll()} ${this.name}`; }.bind(this) }; */ } Object.bindedAppend = function(parent, name, child){ Object.defineProperty(parent.prototype, name, { configurable: true, enumerable: true, get: function(){ if(this === parent.prototype) return child; return this[name] = new Proxy(this, { get: (p, key) => key in child ? child[key] : this[key], set: (p, key, val) => this[key] = val }) } }); return child }; Object.bindedAppend(CreateTest, 'renameObj', { rename: function() { return this.name = `${this.roll()} ${this.name}`; } }); var test3 = new CreateTest("js test"); test3.renameObj.rename(); alert(test3.name) |
Часовой пояс GMT +3, время: 23:53. |