Frontend Development 11 min read

Master 9 Essential JavaScript Techniques: Dynamic Loading, Templates, Reduce, and More

This article walks through nine practical JavaScript patterns—including dynamic script loading, a lightweight template engine, data transformation with reduce, default parameters, one‑time execution, currying, singleton implementation, a simple CommonJS loader, and recursive property access—providing clear code examples for each.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Master 9 Essential JavaScript Techniques: Dynamic Loading, Templates, Reduce, and More

1. Dynamic JS File Loading

In certain scenarios, especially when developing libraries or frameworks, you may need to load and execute JS files dynamically. Below is a simple Promise‑based wrapper.

<code>function loadJS(files, done) {
  const head = document.getElementsByTagName('head')[0];
  Promise.all(files.map(file => new Promise(resolve => {
    const s = document.createElement('script');
    s.type = "text/javascript";
    s.async = true;
    s.src = file;
    s.addEventListener('load', () => resolve(), false);
    head.appendChild(s);
  }))).then(done);
}

loadJS(["test1.js", "test2.js"], () => {
  // user's callback logic
});</code>

2. Implementing a Template Engine

This concise example demonstrates a dynamic template rendering engine that supports variable substitution as well as JS logic such as loops and conditionals.

<code>var template =
  'My favorite sports:' +
  '<%if(this.showSports) {%>' +
  '<% for(var index in this.sports) { %>' +
  '<a><%this.sports[index]%></a>' +
  '<%}%>' +
  '<%} else {%>' +
  '<p>none</p>' +
  '<%}%>';

const code = `with(obj) {
  var r=[];
  r.push("My favorite sports:");
  if(this.showSports){
    for(var index in this.sports){
      r.push("<a>");
      r.push(this.sports[index]);
      r.push("</a>");
    }
  } else {
    r.push("<span>none</span>");
  }
  return r.join("");
}`;

const options = { sports:["swimming","basketball","football"], showSports:true };
const result = new Function("obj", code).apply(options, [options]);
console.log(result);
</code>

3. Using Reduce to Transform Data Structures

Reduce is a powerful tool for reshaping data received from back‑end services. The example groups an array of objects by a specified key.

<code>const arr = [
  { classId:"1", name:"Jack", age:16 },
  { classId:"1", name:"Jon", age:15 },
  { classId:"2", name:"Jenny", age:16 },
  { classId:"3", name:"Jim", age:15 },
  { classId:"2", name:"Zoe", age:16 }
];

function groupArrayByKey(arr = [], key) {
  return arr.reduce((t, v) => (
    (!t[v[key]] && (t[v[key]] = []),
    t[v[key]].push(v),
    t)
  ), {});
}

console.log(groupArrayByKey(arr, "classId"));
</code>

4. Adding Default Values

Functions can provide default arguments or enforce required parameters.

<code>function double(value = 0) {
  return value * 2;
}

const required = () => { throw new Error("This function requires one parameter."); };
function double(value = required()) {
  return value * 2;
}

console.log(double(3)); // 6
console.log(double()); // throws Error
</code>

5. Ensuring a Function Executes Only Once

<code>export function once(fn) {
  let called = false;
  return function() {
    if (!called) {
      called = true;
      fn.apply(this, arguments);
    }
  };
}
</code>

6. Implementing Curry

Curry transforms a multi‑parameter function into a sequence of single‑parameter functions, improving reusability.

<code>function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function(...args2) {
        return curried.apply(this, args.concat(args2));
      };
    }
  };
}

function add(x, y) { return x + y; }
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)); // 3
console.log(curriedAdd(1, 2)); // 3
</code>

7. Implementing the Singleton Pattern

<code>let cache;
class A { /* ... */ }
function getInstance() {
  if (cache) return cache;
  return cache = new A();
}
const x = getInstance();
const y = getInstance();
console.log(x === y); // true
</code>

8. Simple CommonJS Implementation

The core idea of CommonJS is to treat each file as a module with its own scope. The following code provides a minimal implementation of a module loader.

<code>const path = require('path');
const fs = require('fs');

function Module(id) {
  this.id = id;
  this.exports = {};
}

function myRequire(filePath) {
  return Module._load(filePath);
}

Module._cache = {};
Module._load = function(filePath) {
  const realPath = Module._resolveFilename(filePath);
  if (Module._cache[realPath]) return Module._cache[realPath].exports;
  const module = new Module(realPath);
  module.load(realPath);
  return module.exports;
};

Module._extensions = {
  '.js': handleJS,
  '.json': handleJSON
};

function handleJSON(module) {
  const json = fs.readFileSync(module.id, 'utf-8');
  module.exports = JSON.parse(json);
}

function handleJS(module) {
  const js = fs.readFileSync(module.id, 'utf-8');
  const fn = new Function('exports','myRequire','module','__filename','__dirname', js);
  fn.call(module.exports, module.exports, myRequire, module, module.id, path.dirname(module.id));
}

Module._resolveFilename = function(filePath) {
  let absPath = path.resolve(__dirname, filePath);
  if (fs.existsSync(absPath)) return absPath;
  const keys = Object.keys(Module._extensions);
  for (let i = 0; i < keys.length; i++) {
    const currentPath = absPath + keys[i];
    if (fs.existsSync(currentPath)) return currentPath;
  }
};

Module.prototype.load = function(realPath) {
  const extname = path.extname(realPath);
  Module._extensions[extname](this);
};
</code>

9. Recursively Getting Object Properties

A utility function that retrieves nested properties safely, returning a fallback value when the path does not exist.

<code>function get(obj, path, fallback) {
  const parts = path.split('.');
  const key = parts.shift();
  if (typeof obj[key] !== 'undefined') {
    return parts.length > 0 ? get(obj[key], parts.join('.'), fallback) : obj[key];
  }
  return fallback;
}

const user = { info: { name: "Jacky", address: { home: "MLB", company: "AI" } } };
console.log(get(user, "info.name")); // Jacky
console.log(get(user, "info.address.home")); // MLB
console.log(get(user, "info.address.company")); // AI
console.log(get(user, "info.address.abc", "fallback")); // fallback
</code>
JavaScriptfrontend developmentdynamic loadingTemplate Enginecurry
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.