0
\$\begingroup\$

So as I understand it, you should always declare a function before it gets called.

However in the code below, how could this be restructured so that this philosophy is satisfied?

fetchTags is declared here as the 3rd function, somewhere below here I call it from a loadTags function.

After the tags are loaded, I then attached the EventListener and attach the 2nd function scrollingTags.

Once scrollingTags hits bottom and calls loadMoreItems which returns checkScrollLimit and if this !LIMIT_REACHED is true, limit is not reached, it calls fetchTags again which is declared below checkScrollLimit.

My code works so maybe this is a non-issue, just curious how other developers would treat this.

const checkScrollLimit = () => {
    if (!LIMIT_REACHED) {
        const infiniteScroll = true;
        PARAMS.start += this.limit;
        maxlimitCheck() ? LIMIT_REACHED = true : fetchTags(infiniteScroll);
    }
};

const scrollingTags = () => {
    const reachedBottom = () => tagsCol.scrollHeight - tagsCol.scrollTop === tagsCol.offsetHeight;
    const loadMoreItems = () => checkScrollLimit();
    if (reachedBottom()) loadMoreItems();
};

const fetchTags = (infiniteScroll) => {
    LIMIT_REACHED = false;
    return GetTagsFactory.getTags(false, Util.encodeTicker(this.ticker), PARAMS).then((tags) => {
        TOTAL_TAGS = tags.total;
        this.tags = fillTagsList(tags, infiniteScroll);
        tagsCol.addEventListener('scroll', scrollingTags);
        return this.tags;
    });
};
\$\endgroup\$
  • \$\begingroup\$ "you should always declare a function before it gets called." says who? \$\endgroup\$ – BCdotWEB Jan 5 '17 at 15:42
  • 1
    \$\begingroup\$ Try to write pure functions instead of dirty ones, they are more testable and readable. medium.com/javascript-scene/… \$\endgroup\$ – Miguel Lattuada Jan 5 '17 at 18:54
2
\$\begingroup\$

Structure's ok. The functions are all tightly coupled, which may make changes more of a hassle, but it's nothing super terrible.

It could be cleaner if you separated concerns a bit more. E.g. fetchTags would do only that: Fetch tags, but not append them to the page or anything. And checkScrollLimit would do only that, and just return a boolean instead of calling other functions.

Having fetchTags also append stuff to the page is what leads to attaching the event listener, which causes the circular dependency with scrollingTags, which in turn is coupled to checkScrollLimit which is coupled to fetch.... - you get the idea.

So you could add higher-order functions - say, something like an appendTags function which calls fetchTags and fillTagsList and finally adds the event listener. Then fetchTags wouldn't be coupled to scrollingTags and vice versa; a higher-order function(s) would in charge to tying all the ends together.

Still, I'd say it's mostly a non-issue in this particular case. All your functions are defined before they're called, and that's what matters. The JS runtime doesn't care about the order of the function definitions, only that they have been defined before something tries to call them. So, really, you could mix them up however you want.

Sidenote: The scrollingTags function seems a little too complicated, though, what with wrapping checkScrollLimit in another local function. Could just skip that and call it directly.


On a related note, just your edification: If you had used "proper" function declarations - i.e. function foo() {...} – JavaScript would "hoist" those declarations and interpret them before starting the rest of the script evaluation. So in that case, the code would work even if you actually called a function before it had (seemingly) been defined. So, curiously, this works:

foo();

function foo() { ... } // hoisted; evaluated before anything else

but this doesn't:

foo(); // error: foo isn't defined (yet)

var foo = function () { ... } // not hoisted

and nor do the ES6 => declarations.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.