Как сделать, чтобы фабрика возвращала функцию?
Допустим код:
var test = function(name) { console.log('Привет', name); }; test.property = 'Вложенное свойство'; test('Ваня'); //Привет Ваня console.log(test.property); //Вложенное свойство Всё работает, однако с прототипами беда, чтобы их использовать, нужно прибегнуть к фабрикам: function factoryTest() { this.property = 'Вложенное свойство'; this = function(name) {console.log('Привет', name); //ТУТ ОШИБКА - Invalid left-hand side in assignment }; factoryTest.prototype.destroyProperty = function() { if('property' in this) delete this.property; return; }; var test = new factoryTest(); test('Ваня'); //Привет Ваня console.log(test.property); //Вложенное свойство test.destroyPropery(); Понятно, что можно вынести функци в метод, скажем test.hello = function() {...}, однако запись менее удобная в итоге. Как можно решить данную проблему? |
Splik,
Вы пишите бред, скажите что вы хотите получить и для чего это надо. Объект не может быть функцией. Функция - объект, но объект - не функция. :) |
В javascript функции являются полноценными объектами встроенного класса Function. Именно поэтому их можно присваивать переменным, передавать и, конечно, у них есть свойства:
function f() { ... } f.test = 6 ... alert(f.test) // 6 Взял из: http://javascript.ru/basic/functions#funkcii---obekty А что сделать? Я хочу присвоить функции(которую вернёт фабрика, т.е. объекту) прототип, однако сделать это именно кроссбраузерно можно лишь так: Наследование происходит через скрытое свойство прототип [[prototype]], однако единственный кроссбраузерный способ указать прототип - это использовать свойство prototype функции-конструктора. Взял из: http://javascript.ru/tutorial/object...ype-i-prototip Ну вот, что получается в итоге: cоздать функцию я могу, могу даже дать ей прототип чере _proto_, но это не кроссбраузерно, а чтобы сделать кроссбраузерно, надо использовать фабрику(функция конструктор). Но в ней я столкнулся с трудностью, что либо я не могу сделать this = function..., либо прототип не цепляется: function factoryTest() { return function(name) { console.log('Привет', name); }; } function factoryTestInit() { var test = new factoryTest(); test.propetry = 'Свойство'; console.log([test]); //выведет массив, где 0 элементом будет функция из конструктора, однако функции deleteProp из прототипа тут не будет return test; } factoryTest.prototype.deleteProp = function() { if('property' in this) delete this.property return; }; var testObj = new factoryTestInit(); Вот, если в консоли посмотрть на возвращаемую конструктором функцию, то прототип не прокинулся. Однако, если попробовать следующий код: var test = function() { console.log('Test'); }; test.property = 'Свойство'; test.__proto__.secondTest = function() { console.log('Test second'); }; test(); test.secondTest(); console.log(test.property); То всё будет работать как надо. Т.е. в ручную и не кроссбраузерно я могу написать себе функцию и прокинуть к ней прототипы, а вот возможно ли это сделать через фабрику(функцию конструктор) - загадка. |
Цитата:
|
Splik,
Покажите пример использования (вызов метода/функции и рядом в комментарии желаемый результат) |
Первую строчку Вашего ответа не верно прочитал, с тем, что Вы сказали, я согласен.
И то, что 3я строчка не работает - я знаю. Вопрос в том, как добиться того, что я описал выше? В своём втором сообщении в этой теме, я привел еще один пример, но там не прокидывается прототип. |
var test = function() { console.log('Test'); }; test.property = 'Свойство'; test.__proto__.secondTest = function() { console.log('Test second'); }; test(); //Выведет Test test.secondTest(); //Выведет Test second console.log(test.property); //Выведет Свойство Вот желаемый результат, он работает. Однако прототип тут цепляется через __proto__, что не кроссбраузерно (повторяюсь уже который раз :) ), а чтобы сделать кроссбраузерно, надо прототип цеплять к функии конструктор. А вот как сделать через конструктор, я и не пойму. Пример, не работающий: function factoryTest() { return function() { cconsole.log('Test'); }; } function factoryTestInit() { var test = new factoryTest(); test.propetry = 'Свойство'; console.log([test]); //выведет массив, где 0 элементом будет функция из конструктора, однако функции secondTest из прототипа тут не будет return test; } factoryTest.prototype.secondTest = function() { console.log('Test second'); }; var testObj = new factoryTestInit(); testObj(); //Выведет Test testObj.secondTest(); //ХОЧУ ЧТОБЫ МЕТОД ВЫПОЛНИЛСЯ, НО ТУТ БУДЕТ ОШИБКА, ЧТО ТАКОЙ ФУНКЦИИ НЕТ console.log(testObj.property); //Выведет Свойство Извиняюсь за капс, он для наглядности. |
Так как вы хотите сделать не получится. Можно либо изменить прототип всех функций в целом (тогда свойства появятся у всех функций), либо вызывать функцию через дополнительный ключ объекта. Дело в том что конструктор Может вернуть только объект (по крайней мере чтобы он был связан с прототипом). И соответственно "testObj(); //Выведет Test" при условии что testObj вышел из конструктора не возможно.
Но можно сделать чтобы было такое же поведение при другой реализации. |
var FuncFactory = function (data) { var f = data.main; for (var key in data) { if (data.hasOwnProperty(key) && key != 'main') { f[key] = data[key]; } } return f; }; var testObj = FuncFactory({ main: function() { console.log('Test'); }, propetry: 'propetry', secondTest: function () { console.log('Test second'); } }); testObj(); testObj.secondTest(); console.log(testObj.propetry); |
Спасибо, мои догадки оправданы. Часть вопросав отпала. ))
И последнее, что мне не понятно. Почему через конструктор прототип не вешатся, а вот в ручную, через __proto__ - запросто? |
Часовой пояс GMT +3, время: 15:51. |