I’m writing a JavaScript API and for a particular case, I’m wondering which approach is the sexiest. Let’s take an example: writing a VideoPlayer
, I add a getCurrentTime
method which gives the elapsed time since the start.
-
The first approach simply declares
getCurrentTime
as follows:getCurrentTime():number
where
number
is the native number type. This approach includes aCURRENT_TIME_CHANGED
event so that API users can add callbacks to be aware of time changes. Listening to this event would look like the following:myVideoPlayer.addEventListener(CURRENT_TIME_CHANGED, function(evt){ console.log ("current time = "+evt.getDispatcher().getCurrentTime()); });
-
The second approach declares
getCurrentTime
differently:getCurrentTime():CustomNumber
where
CustomNumber
is a custom number object, not the native one. This custom object dispatches aVALUE_CHANGED
event when its value changes, so there is no need for theCURRENT_TIME_CHANGED
event! Just listen to the returned object for value changes! Listening to this event would look like the following:myVideoPlayer.getCurrentTime().addEventListener(VALUE_CHANGED, function(evt){ console.log ("current time = "+evt.getDispatcher().valueOf()); });
Note that
CustomNumber
has avalueOf
method which returns a native number that lets the returnedCustomNumber
object being used as a number, so:var result = myVideoPlayer.getCurrentTime()+5;
will work!
So in the first approach, we listen to an object for a change in its property’s value. In the second one we directly listen to the property for a change on its value. There are multiple pros and cons for each approach, I just want to know which one the developers would prefer to use!
Go with the first approach. When people use a method like getCurrentTime()
and store the returned value, they expect that that value will remain the time at the moment they called the method. Having that value suddenly change is going to be a source of great confusion:
prevTime = myVideoPlayer.getCurrentTime();
//...at some later point
timeElapsed = myVideoPlayer.getCurrentTime() - prevTime;
Now timeElapsed
is 0
, which is wrong. The correct code for that API would be:
prevTime = myVideoPlayer.getCurrentTime().valueOf();
//...at some later point
timeElapsed = myVideoPlayer.getCurrentTime() - prevTime;
But this way is very uncommon, and most people will instinctively use the first method and get confusing bugs.
1