JavaScript Fundamentals
This guide covers essential JavaScript concepts you’ll need before diving into Terra’s framework. This section is not here to teach you how to code, but all the conventions we use at Terra so your code is consistent with the rest of the codebase.
Variables
Section titled “Variables”We don’t care what declaring word you use for variables. We try to stay mostly within ES6 so we use const for almost everything and let for those times you need to assign a variable conditionally after checking some other condition or finishing a loop.
// Example of when to use 'let'let langParam;if (regionParam) { langParam = getLanguageFromRegion(regionParam);}You’ll see a few vars in the wild, mostly in old code, feel free to change them if you’re working on that piece of code. Leave them be if you’re just passing through, though, you know, if it works…
Best practice: Default to const, use let when you need to reassign.
Functions
Section titled “Functions”In keeping with the ES6 conventions, we do prefer to use arrow functions but regular declaration is totally fine.
Naming Convention
Section titled “Naming Convention”- Use
camelCase(starting lowercase). - Be descriptive but don’t use super long names to facilitate readability.
Examples:
getUserData.jsformatPrice.js
Function Parameters
Section titled “Function Parameters”All functions that receive parameters should accept them as an object.
We do this to be consistent in all our functions and to facilitate adding / removing parameters when the function is already integrated in the code. Also this makes it so the order of the parameters is irrelevant, and it’s easier to call our functions without provoking mistakes.
We’ll also always destructure our payload, either in the parenthesis or inside the function, depending mostly on the length of the payload. If we have only a couple elements, destructuring inside the parenthesis is fine. If we have a lot and some defaults, it’s probably more legible to do it inside the function.
// Destructuring in the parenthesisconst yourFunction = ({ a, b, c = "default value" }) => { // Function body};
// Destructuring inside the functionconst yourFunction = (payload) => { const { a, b, c = "default value", d, e, f } = payload; // Function body};
// ❌ DO NOT use the payload object for every parameter ❌const yourFunction = (payload) => { console.log(payload.a); console.log(payload.b); // Function body};Conditional Statements
Section titled “Conditional Statements”We follow a general legibility rule for the use of conditionals:
- If the conditions are lengthy or complex, use full
ifstatements
let typeClass = "";typeClass = "c--card-e--fourth";if (level == "high" && !isIndex) { typeCustomClass = "c--card-e__ft-items__hd__meta__item--fifth";} else if (level == "critical" && !isIndex) { typeCustomClass = "c--card-e__ft-items__hd__meta__item--sixth";}- If you’re contemplating only one condition, with no
else, use anifstatement too
let redirectUrl;if (redirect_link) { redirectUrl = redirect_link?.href ? redirect_link?.href : `${import.meta.env.PUBLIC_API_URL}${getUrl({ ...redirect_link, language })}`;}- If there’s only two conditions and it’s a simple thing, like checking if something exists or not, use a
ternaryoperator
const TitleTag = pretitle ? "h3" : "h2";- If you have many conditions depending on a single variable, use a
switchstatements
let colClass;
switch (option) { case "large": colClass = "f--col-10 f--col-tablets-12"; break; case "medium": colClass = "f--col-8 f--col-tabletl-10 f--col-tablets-12"; break; case "small": colClass = "f--col-6 f--col-tabletl-8 f--col-tabletm-10 f--col-tablets-12"; break; default: colClass = "f--col-8 f--col-tabletl-10 f--col-tablets-12";}forEach
Section titled “forEach”One of our most used loops, when we need to operate inside the loop but we do not need the modified array back.
if (this.DOM.dateElements && webinarSeriesRegion.date) { this.DOM.dateElements.forEach((element) => (element.innerHTML = webinarSeriesRegion.date));} else { this.DOM.dateWrappers.forEach((element) => element.remove());}Syntax is basically the same as in forEach, but it does return the modified array so we can use it later.
const items = data.map((item) => ({ ...item, _key: item._key || Math.random().toString(36).substr(2, 9),}));for ... of
Section titled “for ... of”We use for of when we need to preserve the async nature of a function executed inside a loop. No other loops truly await for the async function to resolve before continuing looping.
for (const [intIndex, element] of elements.entries()) { ... if (boostify && boostify.method == 'click') { ... } else if (inViewport && !shouldLoadInstantly) { // Import library if not already present try { await this.importLibrary(this.asset); // Create instance of the library this.createInstance({ element, config, modifiesHeight, method: "Viewport" }); } catch (error) { console.error(error); this.debug.error(`⚠️ Error loading ${this.libraryName}`, "import"); } } else if (!inViewport && !shouldLoadInstantly) { ... } }If we need to use the index of an element, we usually just use the index available in our forEach or map, but you can also use a regular for loop.
Array Methods
Section titled “Array Methods”Aside from simple methods like push, split, join, etc., we mostly use:
find()
Section titled “find()”Returns the first element that satisfies a condition. Stops searching once found.
export const getWebinarRegion = ({ webinar, userLocation }) => { const matchedRegion = webinar.regions.find((region) => region.value === userLocation); ...};filter()
Section titled “filter()”Returns the filtered array according to the condition.
if (this.regionParam) { const regionsObject = this.regions.filter((region) => region.value == this.regionParam); webinarRegion = getWebinarRegion({ webinar: { regions: regionsObject }, userLocation: this.userInformation?.userLocation, });}Classes
Section titled “Classes”We use classes for most of our framework needs. Each library we import uses a class as a Handler and the backbone of our framework’s functionality is done in classes. Learn more about them here
Next Steps
Section titled “Next Steps”→ Learn about handlers, SWUP, and our component system in Terra’s JavaScript Workflow
Knowledge Check
Test your understanding of this section
Loading questions...