I would like to add a method to a function expression as simply as possible. In my case, I use a function expression, but a function declaration would also be ok. Since functions are objects, I guess it is possible. But how?
Details:
I want to add the method as simply and as directly as possible, so I neither want to use Constructor functions nor inheritance.
The following code adds a method (setListener) to a function (secondsEvent) without Constructors and inheritance, but not within the anonymous function expression, which I would like to achieve somehow (see comments):
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);
The code yields the following output:
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)
.....
Updates:
Originally, I used Douglas Crockford's term "function literal" instead of function expression, but updated the title and question now.
In response to Teemu's suggestion, I tried the following code:
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);
However, its output is the following:
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>
To avoid setting the properties secondsEvent.listener and secondsEvent.setListener each time secondsEvent is called, I use the following:
secondsEvent.listener = secondsEvent.listener || listener1;
secondsEvent.setListener = secondsEvent.setListener || function (newListener) {
secondsEvent.listener = newListener;
console.log("listener now " + secondsEvent.listener.name);
}
Is there a nicer solution for setting the properties only once? Maybe some js initializer idiom? (I know that pulling this out of the function would be another solution, but that leads to my first solution which I want to avoid since it would be much nicer to include the property definitions within the function expression (or function declaration, whichever you use), before they are used.
FUNCTION_NAME.METHOD_NAME = function () {...};. Though I've no clue, how the provided code in the post is relevant to the question ..?document.write(ln)easily leads to reference errors, since it wipes all the previous code out from the document, and creates a new document, if called after the page has been parsed. Useconsolemethods for getting info and debugging.