Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 17.06.2015, 14:35
Новичок на форуме
Отправить личное сообщение для Splik Посмотреть профиль Найти все сообщения от Splik
 
Регистрация: 26.02.2014
Сообщений: 7

Как сделать, чтобы фабрика возвращала функцию?
Допустим код:
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() {...}, однако запись менее удобная в итоге. Как можно решить данную проблему?
Ответить с цитированием
  #2 (permalink)  
Старый 17.06.2015, 15:16
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 12.12.2012
Сообщений: 1,398

Splik,
Вы пишите бред, скажите что вы хотите получить и для чего это надо. Объект не может быть функцией. Функция - объект, но объект - не функция.
Ответить с цитированием
  #3 (permalink)  
Старый 17.06.2015, 16:32
Новичок на форуме
Отправить личное сообщение для Splik Посмотреть профиль Найти все сообщения от Splik
 
Регистрация: 26.02.2014
Сообщений: 7

В 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, 17.06.2015 в 16:45.
Ответить с цитированием
  #4 (permalink)  
Старый 17.06.2015, 16:36
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 12.12.2012
Сообщений: 1,398

Сообщение от Splik
Не соглашусь.
С чем? Я же сказал что функция - это объект. Просто не получится написать ка в 3-ей строке вашего первого примера.
Ответить с цитированием
  #5 (permalink)  
Старый 17.06.2015, 16:48
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 12.12.2012
Сообщений: 1,398

Splik,
Покажите пример использования (вызов метода/функции и рядом в комментарии желаемый результат)
Ответить с цитированием
  #6 (permalink)  
Старый 17.06.2015, 16:50
Новичок на форуме
Отправить личное сообщение для Splik Посмотреть профиль Найти все сообщения от Splik
 
Регистрация: 26.02.2014
Сообщений: 7

Первую строчку Вашего ответа не верно прочитал, с тем, что Вы сказали, я согласен.
И то, что 3я строчка не работает - я знаю.
Вопрос в том, как добиться того, что я описал выше?
В своём втором сообщении в этой теме, я привел еще один пример, но там не прокидывается прототип.
Ответить с цитированием
  #7 (permalink)  
Старый 17.06.2015, 16:53
Новичок на форуме
Отправить личное сообщение для Splik Посмотреть профиль Найти все сообщения от Splik
 
Регистрация: 26.02.2014
Сообщений: 7

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); //Выведет Свойство

Извиняюсь за капс, он для наглядности.

Последний раз редактировалось Splik, 17.06.2015 в 16:58.
Ответить с цитированием
  #8 (permalink)  
Старый 17.06.2015, 17:06
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 12.12.2012
Сообщений: 1,398

Так как вы хотите сделать не получится. Можно либо изменить прототип всех функций в целом (тогда свойства появятся у всех функций), либо вызывать функцию через дополнительный ключ объекта. Дело в том что конструктор Может вернуть только объект (по крайней мере чтобы он был связан с прототипом). И соответственно "testObj(); //Выведет Test" при условии что testObj вышел из конструктора не возможно.
Но можно сделать чтобы было такое же поведение при другой реализации.
Ответить с цитированием
  #9 (permalink)  
Старый 17.06.2015, 17:11
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 12.12.2012
Сообщений: 1,398

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);
Ответить с цитированием
  #10 (permalink)  
Старый 17.06.2015, 17:18
Новичок на форуме
Отправить личное сообщение для Splik Посмотреть профиль Найти все сообщения от Splik
 
Регистрация: 26.02.2014
Сообщений: 7

Спасибо, мои догадки оправданы. Часть вопросав отпала. ))

И последнее, что мне не понятно. Почему через конструктор прототип не вешатся, а вот в ручную, через __proto__ - запросто?

Последний раз редактировалось Splik, 17.06.2015 в 17:21.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как сделать, чтобы при вводе числа в поле добавлялись разделители групп разрядов? Hurray Элементы интерфейса 13 18.02.2015 14:07
Как сделать, чтобы скрипт работал только если текущий документ iframe? ruslan_mart Общие вопросы Javascript 10 14.01.2015 13:56
Как сделать так чтобы тут в pupop окне показывалась не сайт : http://www.foo-site.ru sarik Общие вопросы Javascript 1 05.03.2013 10:33
как сделать чтобы когда убираю галочку с чекбокса то текст убралось:) ? sarik Общие вопросы Javascript 9 27.02.2013 15:03
как сделать чтобы оба скрипти работали sarik Общие вопросы Javascript 18 15.02.2013 15:43