9 Useful JavaScript Tricks and Code Snippets for Frontend Development
This article presents nine practical JavaScript techniques—including dynamic script loading, a lightweight template engine, array grouping with reduce, default parameters, single‑execution wrappers, currying, the singleton pattern, a simple CommonJS implementation, and recursive property access—each illustrated with clear code examples for front‑end developers.
In everyday development work, the author has collected a set of common and highly useful JavaScript tricks and code snippets, selecting nine of them for reference.
1. Dynamically Load JS Files
In special scenarios such as library or framework development, you may need to load and execute JS files dynamically. The following function wraps this logic with Promise for asynchronous handling.
function loadJS(files, done) {
// Get head element
const head = document.getElementsByTagName('head')[0];
Promise.all(files.map(file => {
return new Promise(resolve => {
// Create script tag and add to head
const s = document.createElement('script');
s.type = "text/javascript";
s.async = true;
s.src = file;
// Listen for load event, then resolve
s.addEventListener('load', e => resolve(), false);
head.appendChild(s);
});
})).then(done); // All completed, execute user callback
}
loadJS(["test1.js", "test2.js"], () => {
// User callback logic
});2. Implement a Simple Template Engine
The example demonstrates a minimal dynamic template rendering engine that supports variable substitution, for loops, and if statements. Detailed explanation is provided in another article.
// This is a template containing JS code
var template =
'My avorite sports:' +
'<%if(this.showSports) {%>'+
'<% for(var index in this.sports) { %>'+
'<a><%this.sports[index]%></a>'+
'<%}%>'+
'<%} else {%>'+
'<p>none</p>'+
'<%}%>';
// Build executable function string
const code = `with(obj) {
var r=[];
r.push("My avorite sports:");
if(this.showSports) {
for(var index in this.sports) {
r.push("
");
r.push(this.sports[index]);
r.push("
");
}
} else {
r.push("
none
");
}
return r.join("");
}`;
// Data to render
const options = {
sports: ["swimming", "basketball", "football"],
showSports: true
};
// Build function and invoke with proper this
result = new Function("obj", code).apply(options, [options]);
console.log(result);3. Use reduce for Data Structure Transformation
When the front‑end needs to reshape data received from the back‑end, reduce provides a concise solution. The example groups an array of objects by a specified key.
const arr = [
{ classId: "1", name: "张三", age: 16 },
{ classId: "1", name: "李四", age: 15 },
{ classId: "2", name: "王五", age: 16 },
{ classId: "3", name: "赵六", age: 15 },
{ classId: "2", name: "孔七", age: 16 }
];
groupArrayByKey(arr, "classId");
function groupArrayByKey(arr = [], key) {
return arr.reduce((t, v) => (!t[v[key]] && (t[v[key]] = []), t[v[key]].push(v), t), {});
}4. Add Default Values
Functions can provide default parameters or enforce required arguments. The snippet shows both approaches.
function double() {
return value * 2
}
// Provide a default value of 0 when not passed
function double(value = 0) {
return value * 2
}
// Throw an error if a required argument is missing
const required = () => {
throw new Error("This function requires one parameter.")
}
function double(value = required()) {
return value * 2
}
double(3) // 6
double() // throws Error5. Ensure a Function Executes Only Once
Using a closure, the once wrapper guarantees that the wrapped function runs a single time.
export function once(fn) {
// Use closure to track execution
let called = false
return function() {
if (!called) {
called = true
fn.apply(this, arguments)
}
}
}6. Implement Currying
Currying transforms a multi‑parameter function into a series of unary functions, improving flexibility and readability.
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)); // 37. Implement the Singleton Pattern
The singleton ensures a class has only one instance and provides a global access point.
let cache;
class A {
// ...
}
function getInstance() {
if (cache) return cache;
return cache = new A();
}
const x = getInstance();
const y = getInstance();
console.log(x === y); // true8. Implement a Simple CommonJS Specification
The code reproduces the core ideas of CommonJS: module isolation, exports , and a custom myRequire loader.
// id: full file name
const path = require('path');
const fs = require('fs');
function Module(id) {
this.id = id; // unique identifier
this.exports = {};
}
function myRequire(filePath) {
return Module._load(filePath);
}
Module._cache = {};
Module._load = function(filePath) {
const realPath = Module._resoleveFilename(filePath);
let cacheModule = Module._cache[realPath];
if (cacheModule) return cacheModule.exports;
let 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');
let fn = new Function('exports', 'myRequire', 'module', '__filename', '__dirname', js);
let exports = module.exports;
fn.call(exports, exports, myRequire, module, module.id, path.dirname(module.id));
}
Module._resolveFilename = function(filePath) {
let absPath = path.resolve(__dirname, filePath);
let exists = fs.existsSync(absPath);
if (exists) return absPath;
let keys = Object.keys(Module._extensions);
for (let i = 0; i < keys.length; i++) {
let currentPath = absPath + keys[i];
if (fs.existsSync(currentPath)) return currentPath;
}
};
Module.prototype.load = function(realPath) {
let extname = path.extname(realPath);
Module._extensions[extname](this);
};9. Recursively Get Object Properties
A utility function get retrieves nested properties using a dot‑separated path, returning a fallback value when the property does not exist.
const user = {
info: {
name: "张三",
address: { home: "Shaanxi", company: "Xian" },
},
};
// obj: target object, path: property path, fallback: default value
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 if key not found
return fallback;
}
console.log(get(user, "info.name")); // 张三
console.log(get(user, "info.address.home")); // Shaanxi
console.log(get(user, "info.address.company")); // Xian
console.log(get(user, "info.address.abc", "fallback")); // fallbackThese nine JavaScript tricks aim to improve development efficiency and code quality for front‑end engineers.
ByteFE
Cutting‑edge tech, article sharing, and practical insights from the ByteDance frontend team.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.