Я хотел бы добавить метод к выражению функции настолько просто, насколько это возможно.В моем случае я использую выражение функции, но объявление функции также будет в порядке.Поскольку функции являются объектами, я думаю, что это возможно. Но как?
Подробности:
Я хочу добавить метод как можно более просто и максимально напрямую, поэтому я не хочу ни использовать функции конструктора, ни наследование,
Следующий код добавляет метод (setListener
) к функции (secondsEvent
) без конструкторов и наследования, но не в выражении анонимной функции, чего я хотел бы достичь каким-либо образом (см. Комментарии):
function listener1 (date) {
console.log("listener1: " + date);
}
function listener2 (date) {
console.log("listener2: " + date);
}
var secondsEvent = function () {
//The following causes "listener is not defined" in firefox console
//listener: listener1,
//The following causes "function statement requires a name" in firefox console,
//and if I give the function a name, I get "secondsEvent.setListener is not a function".
//Thus I add the property after this function expression.
//setListener: function (newListener) {
// listener = newListener;
//},
secondsEvent.listener(new Date());
var timeout = setTimeout(secondsEvent, 1000);
}
// Thus the following 5 lines are needed.
secondsEvent.listener = listener1;
secondsEvent.setListener = function (newListener) {
secondsEvent.listener = newListener;
console.log("listener now " + secondsEvent.listener.name);
}
secondsEvent();
secondsEvent.setListener(listener2);
Код дает следующий вывод:
listener1: Fri Dec 28 2018 21:55:05 GMT+0100 (Central European Standard Time)
listener now listener2
listener2: Fri Dec 28 2018 21:55:06 GMT+0100 (Central European Standard Time)
listener2: Fri Dec 28 2018 21:55:07 GMT+0100 (Central European Standard Time)
.....
Обновления:
Первоначально я использовал термин Дугласа Крокфорда "«литерал функции» вместо выражения функции, но теперь обновил заголовок и вопрос.
В ответ на предложение Теему я попробовал следующий код:
function listener1 (date) {
console.log("listener1: "+date + "<br>");
}
function listener2 (date) {
console.log("listener2: "+date + "<br>");
}
var secondsEvent = function () {
secondsEvent.listener = listener1;
secondsEvent.setListener = function (newListener) {
secondsEvent.listener = newListener;
console.log("listener now " + secondsEvent.listener.name);
}
clearTimeout(secondsEvent.timeout);
secondsEvent.listener(new Date());
secondsEvent.timeout = setTimeout(secondsEvent, 1000);
};
secondsEvent();
secondsEvent.setListener(listener2);
Однако его выходные данные выглядят следующим образом:
listener1: Sat Dec 29 2018 10:47:48 GMT+0100 (Central European Standard Time)<br> test.js:2:5
listener now listener2 test.js:27:2
listener1: Sat Dec 29 2018 10:47:49 GMT+0100 (Central European Standard Time)<br> test.js:2:5
listener1: Sat Dec 29 2018 10:47:50 GMT+0100 (Central European Standard Time)<br>
Чтобы не задавать свойства secondsEvent.listener
и secondsEvent.setListener
каждый раз, когда secondsEvent
называется, я использую следующее:
secondsEvent.listener = secondsEvent.listener || listener1;
secondsEvent.setListener = secondsEvent.setListener || function (newListener) {
secondsEvent.listener = newListener;
console.log("listener now " + secondsEvent.listener.name);
}
Есть ли более хорошее решение для установки свойств только один раз?Может быть, некоторые JS инициализатор идиома?(Я знаю, что извлечение этого из функции было бы другим решением, но это приводит к моему первому решению, которого я хочу избежать, так как было бы намного лучше включить определения свойств в выражение функции (или объявление функции, в зависимости от того, что вы используете)), прежде чем они будут использованы.