Lodash Utilities — Strings, Math, Type Checks & Performance Optimization
Lodash utility functions handle string conversion, math helpers, type checks, and templating — the everyday JavaScript tasks that native code does not simplify.
What You’ll Learn
- String utilities:
_.camelCase,_.kebabCase,_.snakeCase,_.escape,_.unescape,_.template,_.truncate - Math utilities:
_.random,_.range,_.clamp,_.inRange,_.round - Type checking:
_.isArray,_.isPlainObject,_.isEqual,_.isEmpty,_.isNil - Lazy evaluation with
_.chain()+.commit(),_.thru,_.iteratee
Why Utility Functions Matter
The difference between a good developer and a great one often comes down to tooling knowledge. String manipulation, type checking, and math helpers seem mundane — until you have to generate 10,000 sequential IDs, safely compare deeply nested objects, or handle user input that could contain XSS vectors.
In Durga Antivirus Pro, _.escape sanitizes file paths and user-generated scan names before rendering. _.camelCase and _.kebabCase normalize threat category names from various threat intelligence feeds. _.isEqual deep-compares configuration snapshots to detect unauthorized changes. And _.range generates paginated lists of scan results efficiently.
Learning Path
flowchart LR
A["Objects &<br/>Functions"] --> B["Utilities &<br/>Performance"]
B --> C["Real Project:<br/>String Studio"]
B --> D["Next Topic:<br/>Axios"]
style B fill:#38bdf8,color:#0f172a,stroke:#38bdf8,stroke-width:2px
style C fill:#22c55e,color:#0f172a
typeof, instanceof, and the concept of truthy/falsy values.String Utilities
Lodash string methods handle edge cases that native JavaScript string methods don’t: accented characters, Unicode normalization, mixed-case inputs, and special characters.
_.camelCase, _.kebabCase, _.snakeCase, _.startCase
These convert between naming conventions — essential when your API returns snake_case but your JavaScript code uses camelCase:
import camelCase from 'lodash/camelCase';
import kebabCase from 'lodash/kebabCase';
import snakeCase from 'lodash/snakeCase';
import startCase from 'lodash/startCase';
// camelCase — used in JavaScript variables and functions
camelCase('Foo Bar'); // 'fooBar'
camelCase('--foo-bar--'); // 'fooBar'
camelCase('__FOO_BAR__'); // 'fooBar'
// kebabCase — used in URLs and CSS classes
kebabCase('Foo Bar'); // 'foo-bar'
kebabCase('camelCase'); // 'camel-case'
// snakeCase — used in database columns and Python
snakeCase('Foo Bar'); // 'foo_bar'
// startCase — used for human-readable titles
startCase('fooBar'); // 'Foo Bar'
Why not just use .toLowerCase().replace(/ /g, '-')? Because that naive approach breaks on edge cases like '--foo-bar--' (double hyphens), '__FOO_BAR__' (underscores), and 'camelCase' (no spaces). Lodash handles all of these correctly.
_.escape and _.unescape — HTML Sanitization
These protect against XSS (Cross-Site Scripting) attacks by converting HTML special characters to their entity equivalents:
import escape from 'lodash/escape';
import unescape from 'lodash/unescape';
escape('<script>alert("xss")</script>');
// '<script>alert("xss")</script>'
unescape('<tag>');
// '<tag>'
When to use: Always escape user-generated content before inserting it into HTML. Even if you use a framework like React that handles most escaping, _.escape is useful for server-rendered content or raw HTML templates.
_.template — JavaScript Template Engine
_.template compiles a string with embedded expressions into a reusable function. Think of it as mail merge for code:
import template from 'lodash/template';
// Step 1: Compile the template into a function
const compiled = template('<h1><%= title %></h1><p><%= message %></p>');
// Step 2: Execute with data
const html = compiled({ title: 'Hello', message: 'World' });
// '<h1>Hello</h1><p>World</p>'
Three delimiter types:
| Delimiter | Behavior | Use Case |
|---|---|---|
<%= %> | Interpolate (plain) | Output values as-is |
<%- %> | Interpolate (escaped) | Auto-escape HTML |
<% %> | Execute JavaScript | Loops, conditionals |
// Escaped output — safe for user input
const safe = template('<p><%- userInput %></p>');
safe({ userInput: '<script>alert(1)</script>' });
// '<p><script>alert(1)</script></p>'
// With loops
const list = template('<ul><% items.forEach(function(item) { %><li><%= item %></li><% }); %></ul>');
list({ items: ['a', 'b', 'c'] });
// '<ul><li>a</li><li>b</li><li>c</li></ul>'
_.truncate — Cut Text to Length
Truncates a string to a maximum length, adding an omission suffix:
import truncate from 'lodash/truncate';
truncate('The quick brown fox jumps over the lazy dog', { length: 20 });
// 'The quick brown fox...'
truncate('Short text', { length: 30 });
// 'Short text' — no truncation needed
// Custom omission
truncate('Long text that needs to be cut off', {
length: 15,
omission: '... (more)'
});
// 'Long text... (more)'
// Word-boundary aware
truncate('The quick brown fox', {
length: 12,
separator: /\s+/
});
// 'The quick...'
Other String Helpers
import pad from 'lodash/pad';
import repeat from 'lodash/repeat';
import startsWith from 'lodash/startsWith';
pad('abc', 8); // ' abc '
pad('abc', 8, '_-'); // '_-abc_-_'
repeat('*', 5); // '*****'
startsWith('hello', 'he'); // true
Math Utilities
_.random — Generate Random Numbers
import random from 'lodash/random';
random(0, 10); // Random integer between 0 and 10 (inclusive)
random(5); // Random integer between 0 and 5
random(0, 10, true); // Random FLOAT between 0 and 10
Without the third argument (true), the result is always an integer. Pass true for floating-point.
_.range — Create Sequential Arrays
Think of _.range as a number-line generator — perfect for loops, pagination, and test data:
import range from 'lodash/range';
range(4); // [0, 1, 2, 3]
range(1, 5); // [1, 2, 3, 4]
range(0, 20, 5); // [0, 5, 10, 15]
range(0, -4, -1); // [0, -1, -2, -3]
_.clamp and _.inRange — Bounds Checking
_.clamp constrains a value between a minimum and maximum — like a volume slider that can’t go below 0 or above 100:
import clamp from 'lodash/clamp';
import inRange from 'lodash/inRange';
clamp(-10, -5, 5); // -5 (brought up to minimum)
clamp(10, -5, 5); // 5 (brought down to maximum)
clamp(3, -5, 5); // 3 (stays unchanged)
inRange(3, 2, 4); // true (2 <= 3 < 4)
inRange(4, 8); // true (0 <= 4 < 8 — start defaults to 0)
_.round, _.floor, _.ceil — Precision Rounding
import round from 'lodash/round';
import floor from 'lodash/floor';
import ceil from 'lodash/ceil';
round(4.006); // 4
round(4.006, 2); // 4.01
round(4160, -2); // 4200 (rounds to nearest hundred)
floor(4.006, 2); // 4
ceil(4.006, 2); // 4.01
Type Checking
Why Lodash Type Checks?
JavaScript’s typeof operator has well-known pitfalls: typeof null returns 'object', typeof [] returns 'object', and typeof can’t distinguish between different object types. Lodash type-checking methods are reliable across environments, including cross-frame scenarios where instanceof fails.
_.isArray, _.isPlainObject
import isArray from 'lodash/isArray';
import isPlainObject from 'lodash/isPlainObject';
isArray([]); // true
isArray(new Array(5)); // true
isArray({}); // false
isPlainObject({}); // true
isPlainObject(new Object()); // true
isPlainObject(new Date()); // false
isPlainObject(Object.create(null)); // true
_.isEqual — Deep Comparison
This is one of the most useful Lodash methods. It performs a deep comparison between two values — recursively checking every nested property:
import isEqual from 'lodash/isEqual';
isEqual({ a: 1, b: { c: 2 } }, { a: 1, b: { c: 2 } });
// true — deeply equal
isEqual([1, 2, 3], [1, 2, 3]);
// true
isEqual(new Date(2023, 0, 1), new Date(2023, 0, 1));
// true — Date objects compared by value
isEqual(NaN, NaN);
// true — NaN equals NaN (unlike === which says false)
_.isEmpty
Checks if a value is “empty” — works across collections, strings, maps, and sets:
import isEmpty from 'lodash/isEmpty';
isEmpty(null); // true
isEmpty(undefined); // true
isEmpty(''); // true
isEmpty([]); // true
isEmpty({}); // true
isEmpty(new Map()); // true
isEmpty(new Set()); // true
isEmpty('hello'); // false
isEmpty([1]); // false
isEmpty({ a: 1 }); // false
_.isEmpty(0) returns true, and _.isEmpty(true) returns true. These are primitives that have no enumerable properties, so Lodash considers them “empty.” If you need to check for null/undefined specifically, use _.isNil._.isNil and Other Checks
import isNil from 'lodash/isNil';
import isNull from 'lodash/isNull';
import isUndefined from 'lodash/isUndefined';
import isFunction from 'lodash/isFunction';
import isString from 'lodash/isString';
import isNumber from 'lodash/isNumber';
import isDate from 'lodash/isDate';
import isRegExp from 'lodash/isRegExp';
isNil(null); // true
isNil(undefined); // true
isNil(0); // false
Performance & Lazy Evaluation
How Lazy Evaluation Works
You learned about _.chain() in the Getting Started guide. Here’s the deeper performance story:
Without chaining, each Lodash method creates an intermediate array that gets passed to the next method:
// Eager evaluation — three passes over the data
const filtered = _.filter(data, n => n % 2 === 0); // Pass 1
const mapped = _.map(filtered, n => n * 3); // Pass 2
const result = _.take(mapped, 10); // Pass 3
With chaining, Lodash uses lazy evaluation. It doesn’t execute anything until .value() is called. At that point, it can reorder operations for maximum efficiency:
// Lazy evaluation — single pass
const result = _.chain(data)
.filter(n => n % 2 === 0)
.map(n => n * 3)
.take(10)
.value();Lodash internally recognizes that _.take(10) means we only need 10 results. So it pushes the filter and map operations to only process enough elements to produce 10 outputs. On a million-element array, this processes ~20 elements instead of 1,000,000.
_.commit() — Split a Chain
_.commit() forces the chain to execute intermediate steps and return a wrapped result, allowing you to split a long pipeline:
const players = [
{ name: 'Alice', score: 90 },
{ name: 'Bob', score: 70 },
{ name: 'Charlie', score: 95 },
];
const wrapped = _.chain(players)
.filter(p => p.score > 80)
.commit(); // Executes filter, returns new wrapper
// Continue chaining on the filtered subset
wrapped.map('name').value();
// ['Alice', 'Charlie']
_.thru — Inject Custom Logic
Pass the intermediate value through any function in the middle of a chain:
const result = _.chain([1, 2, 3, 4])
.map(n => n * 2)
.thru(arr => arr.join(':'))
.value();
// '2:4:6:8'
_.iteratee — The Engine Behind Shorthands
Every time you pass a string like 'name' or an object like { active: true } to a Lodash method, _.iteratee converts it into a function behind the scenes:
import iteratee from 'lodash/iteratee';
// Property name → function that extracts that property
iteratee('name')({ name: 'Alice' }); // 'Alice'
// Property path → function that extracts deeply
iteratee('address.city')({ address: { city: 'NYC' } }); // 'NYC'
// Object match → function that checks partial match
iteratee({ active: true })({ active: true, age: 25 }); // true
// Function → passthrough (no conversion needed)
iteratee(n => n * 2)(5); // 10
Common Mistakes
1. Using _.isEmpty with Numbers or Booleans
// These are probably not what you expect:
_.isEmpty(0); // true
_.isEmpty(true); // true
_.isEmpty('false'); // false (has length 5)
// Use _.isNil for null/undefined checks
// Use _.isNumber for number checks
2. Forgetting _.template Returns a Function
// ❌ Tries to render immediately — returns a function, not a string
const html = template('<%= name %>', { name: 'Alice' });
// ✅ Compile first, then execute
const compiled = template('<%= name %>');
const html = compiled({ name: 'Alice' });3. Not Understanding _.random Return Types
random(0, 10); // Integer (default behavior)
random(0, 10, true); // Float
If you need 2 decimal places, chain with _.round:
_.round(_.random(0, 10, true), 2);4. Naive String Replacement Instead of Case Conversion
// ❌ Breaks on edge cases
'FOO_BAR'.toLowerCase().replace(/_/g, '-'); // 'foo-bar' — OK but...
// ❌ What about camelCase input?
'fooBar'.toLowerCase().replace(/_/g, '-'); // 'foobar' — lost the capital B!
// ✅ Lodash handles everything
_.kebabCase('fooBar'); // 'foo-bar'
5. Using Lazy Chaining on Tiny Datasets
For arrays with fewer than ~100 elements, the overhead of building a chain wrapper exceeds any performance benefit. Use direct method calls or native methods for small data.
Practice Questions
1. What does _.kebabCase('helloWorld') return?
Answer: 'hello-world'. It detects the capital W and inserts a hyphen.
2. Why is _.isEqual(NaN, NaN) true when NaN === NaN is false?
Answer: JavaScript’s === considers NaN not equal to anything (per IEEE 754). _.isEqual uses the SameValueZero algorithm which treats NaN as equal to itself, making it more useful for deep comparison.
3. What is the difference between <%= %> and <%- %> in _.template?
Answer: <%= %> outputs the value as-is (no escaping). <%- %> HTML-escapes the output. Use <%- %> for user-generated content to prevent XSS.
4. How does lazy evaluation improve performance in _.chain()?
Answer: Lazy evaluation defers computation until .value() is called, allowing Lodash to reorder operations (e.g., pushing _.take(10) earlier) so filter/map only process the minimum elements needed instead of the entire collection.
Challenge
Build a URL slug generator using Lodash utilities: start with 'My Durga Antivirus Scan Report: Results for 2024!', convert it to a URL-safe slug, truncate it to 30 characters (without breaking mid-word), and output the final slug. Expected approach: _.kebabCase → _.truncate with word-boundary separator. Verify the result starts with 'my-durga-antivirus-scan'.
FAQ
Try It Yourself
Experiment with case conversion, templating, slug generation, and random data in this interactive sandbox:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Lodash String Studio</title>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: system-ui, -apple-system, sans-serif; background: #0f172a; color: #e2e8f0; padding: 2rem; }
.container { max-width: 1100px; margin: 0 auto; }
h1 { font-size: 1.75rem; margin-bottom: 0.25rem; }
.subtitle { color: #94a3b8; margin-bottom: 1.5rem; }
.tabs { display: flex; gap: 0.25rem; margin-bottom: 1.5rem; border-bottom: 1px solid #334155; }
.tab { padding: 0.5rem 1rem; cursor: pointer; font-size: 0.875rem; color: #94a3b8; background: none; border: none; border-bottom: 2px solid transparent; }
.tab:hover { color: #e2e8f0; }
.tab.active { color: #38bdf8; border-bottom-color: #38bdf8; }
.panel { display: none; }
.panel.active { display: block; }
.card { background: #1e293b; border-radius: 0.75rem; padding: 1.5rem; border: 1px solid #334155; margin-bottom: 1rem; }
.card h2 { font-size: 1.05rem; margin-bottom: 0.75rem; color: #38bdf8; }
.card h3 { font-size: 0.85rem; color: #94a3b8; margin-bottom: 0.5rem; text-transform: uppercase; letter-spacing: 0.05em; }
textarea, input, select { width: 100%; background: #0f172a; color: #e2e8f0; border: 1px solid #334155; border-radius: 0.375rem; padding: 0.625rem; font-family: monospace; font-size: 0.875rem; }
textarea { min-height: 80px; resize: vertical; }
.output-box { background: #0f172a; border: 1px solid #334155; border-radius: 0.375rem; padding: 0.75rem; min-height: 50px; font-family: monospace; font-size: 0.8125rem; white-space: pre-wrap; word-break: break-all; margin-top: 0.5rem; }
.output-box.success { border-color: #22c55e; }
.output-box.error { border-color: #ef4444; color: #fca5a5; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 1rem; }
.btn { background: #38bdf8; color: #0f172a; border: none; padding: 0.4rem 1rem; border-radius: 0.375rem; font-weight: 600; cursor: pointer; font-size: 0.85rem; }
.btn:hover { background: #7dd3fc; }
.btn-outline { background: transparent; color: #38bdf8; border: 1px solid #38bdf8; }
.btn-outline:hover { background: #38bdf8; color: #0f172a; }
.btn-sm { padding: 0.25rem 0.5rem; font-size: 0.75rem; }
.flex { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
.stat { color: #94a3b8; font-size: 0.8rem; margin-top: 0.25rem; }
.badge { background: #334155; padding: 0.125rem 0.375rem; border-radius: 0.25rem; font-size: 0.7rem; color: #94a3b8; }
@media (max-width: 768px) { .grid-2, .grid-3 { grid-template-columns: 1fr; } }
</style>
</head>
<body>
<div class="container">
<h1>String Studio</h1>
<p class="subtitle">Case conversion, templating, slug generation, truncation, and random data</p>
<div class="tabs">
<button class="tab active" onclick="switchTab('case', this)">Case Converter</button>
<button class="tab" onclick="switchTab('template', this)">Template Engine</button>
<button class="tab" onclick="switchTab('slug', this)">Slug Generator</button>
<button class="tab" onclick="switchTab('random', this)">Random Data</button>
</div>
<div id="panel-case" class="panel active">
<div class="grid-2">
<div class="card">
<h2>Input</h2>
<textarea id="caseInput" oninput="updateCase()">hello world from Lodash</textarea>
<div class="flex" style="margin-top:0.5rem;">
<button class="btn btn-sm btn-outline" onclick="document.getElementById('caseInput').value='FOO BAR baz QUX'; updateCase()">UPPER mixed</button>
<button class="btn btn-sm btn-outline" onclick="document.getElementById('caseInput').value='--snake_case--camelCase'; updateCase()">Edge case</button>
</div>
</div>
<div class="card">
<h2>Transformations</h2>
<div id="caseResults"></div>
</div>
</div>
</div>
<div id="panel-template" class="panel">
<div class="grid-2">
<div class="card">
<h2>Template</h2>
<textarea id="templateInput" rows="5"><h1><%= title %></h1>
<p>Welcome, <%- user.name %>!</p>
<ul><% _.forEach(items, function(item) { %>
<li><%= item %></li><% }); %></ul></textarea>
<h3 style="margin-top:0.75rem;">Data (JSON)</h3>
<textarea id="templateData" rows="5">{
"title": "Hello World",
"user": { "name": "<script>Alice</script>" },
"items": ["Alpha", "Beta", "Gamma"]
}</textarea>
<button class="btn" style="margin-top:0.5rem;" onclick="runTemplate()">Render</button>
</div>
<div class="card">
<h2>Rendered HTML</h2>
<div class="output-box success" id="templateOutput" style="min-height:120px;">Click "Render"</div>
<div class="stat" id="templateStat">--</div>
</div>
</div>
</div>
<div id="panel-slug" class="panel">
<div class="grid-2">
<div class="card">
<h2>Title / Text</h2>
<textarea id="slugInput" oninput="updateSlug()">My Blog Post Title: Tips & Tricks for 2024!</textarea>
<div class="flex" style="margin-top:0.5rem;">
<button class="btn btn-sm btn-outline" onclick="copySlug()">Copy Slug</button>
<label style="color:#94a3b8;font-size:0.85rem;">Max length: <input type="number" id="slugMax" value="40" style="width:60px;display:inline;" oninput="updateSlug()" /></label>
</div>
</div>
<div class="card">
<h2>Slug Variants</h2>
<div id="slugResults"></div>
</div>
</div>
</div>
<div id="panel-random" class="panel">
<div class="grid-2">
<div class="card">
<h2>Random Generator</h2>
<div class="flex">
<button class="btn" onclick="generateRandom()">Generate</button>
<label style="color:#94a3b8;font-size:0.85rem;">Count: <input type="number" id="randomCount" value="5" min="1" max="20" style="width:60px;display:inline;" /></label>
</div>
<div class="grid-3" style="margin-top:1rem;">
<div><h3>Integers</h3><div class="output-box" id="randomInts" style="min-height:80px;">--</div></div>
<div><h3>Floats (0-1)</h3><div class="output-box" id="randomFloats" style="min-height:80px;">--</div></div>
<div><h3>Range</h3><div class="output-box" id="randomRange" style="min-height:80px;">--</div></div>
</div>
</div>
<div class="card">
<h2>Helpers</h2>
<div>
<h3>_.clamp</h3>
<div style="display:flex;gap:0.5rem;align-items:center;flex-wrap:wrap;margin-top:0.25rem;">
<input type="number" id="clampVal" value="150" style="width:80px;" />
<span style="color:#94a3b8;">to</span>
<input type="number" id="clampMin" value="0" style="width:80px;" />
<span style="color:#94a3b8;">-</span>
<input type="number" id="clampMax" value="100" style="width:80px;" />
<button class="btn btn-sm" onclick="runClamp()">Clamp</button>
<strong id="clampResult" style="color:#38bdf8;">--</strong>
</div>
</div>
<div style="margin-top:1rem;">
<h3>_.range</h3>
<div style="display:flex;gap:0.5rem;align-items:center;flex-wrap:wrap;margin-top:0.25rem;">
<input type="text" id="rangeParams" value="1, 10, 2" style="width:150px;" placeholder="start, end, step" />
<button class="btn btn-sm" onclick="runRange()">Range</button>
<strong id="rangeResult" style="color:#38bdf8;font-size:0.8rem;">--</strong>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function switchTab(name, btn) {
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
document.querySelectorAll('.panel').forEach(p => p.classList.remove('active'));
btn.classList.add('active');
document.getElementById('panel-' + name).classList.add('active');
}
function updateCase() {
const val = document.getElementById('caseInput').value;
if (!val) { document.getElementById('caseResults').innerHTML = ''; return; }
document.getElementById('caseResults').innerHTML = `
<div class="stat">camelCase: <strong>${_.camelCase(val)}</strong></div>
<div class="stat">kebabCase: <strong>${_.kebabCase(val)}</strong></div>
<div class="stat">snakeCase: <strong>${_.snakeCase(val)}</strong></div>
<div class="stat">startCase: <strong>${_.startCase(val)}</strong></div>
<div class="stat">lowerCase: <strong>${_.lowerCase(val)}</strong></div>
<div class="stat">upperCase: <strong>${_.upperCase(val)}</strong></div>
<div class="stat">escape: <strong>${_.escape(val)}</strong></div>
<div class="stat">unescape: <strong>${_.unescape(_.escape(val))}</strong></div>
`;
}
function runTemplate() {
const tmpl = document.getElementById('templateInput').value;
const dataStr = document.getElementById('templateData').value;
let data;
try { data = JSON.parse(dataStr); } catch {
document.getElementById('templateOutput').textContent = 'Invalid JSON data';
document.getElementById('templateOutput').className = 'output-box error';
return;
}
try {
const compiled = _.template(tmpl);
const html = compiled(data);
document.getElementById('templateOutput').innerHTML = html;
document.getElementById('templateOutput').className = 'output-box success';
document.getElementById('templateStat').innerHTML = 'Rendered ' + html.length + ' chars';
} catch (e) {
document.getElementById('templateOutput').textContent = 'Template error: ' + e.message;
document.getElementById('templateOutput').className = 'output-box error';
}
}
function updateSlug() {
const val = document.getElementById('slugInput').value;
const max = parseInt(document.getElementById('slugMax').value) || 40;
if (!val) { document.getElementById('slugResults').innerHTML = ''; return; }
const slug = _.kebabCase(val);
const truncated = _.truncate(slug, { length: max, omission: '' });
document.getElementById('slugResults').innerHTML = `
<div class="stat">kebabCase slug: <strong>${slug}</strong></div>
<div class="stat">Truncated (${max}): <strong>${truncated}</strong></div>
<div class="stat">snakeCase: <strong>${_.snakeCase(val)}</strong></div>
<div class="stat">slug length: <strong>${slug.length}</strong> chars</div>
`;
}
function copySlug() {
const slug = _.kebabCase(document.getElementById('slugInput').value);
navigator.clipboard.writeText(slug).then(() => alert('Slug copied: ' + slug));
}
function generateRandom() {
const count = parseInt(document.getElementById('randomCount').value) || 5;
const ints = _.times(count, () => _.random(1, 100));
const floats = _.times(count, () => _.random(0, 1, true).toFixed(4));
const range = _.times(count, () => _.random(10, 50));
document.getElementById('randomInts').textContent = ints.join(', ');
document.getElementById('randomFloats').textContent = floats.join(', ');
document.getElementById('randomRange').textContent = range.join(', ');
}
function runClamp() {
const val = parseFloat(document.getElementById('clampVal').value);
const min = parseFloat(document.getElementById('clampMin').value);
const max = parseFloat(document.getElementById('clampMax').value);
document.getElementById('clampResult').textContent = _.clamp(val, min, max);
}
function runRange() {
const str = document.getElementById('rangeParams').value;
const parts = str.split(',').map(s => parseInt(s.trim()));
if (parts.length < 1) return;
const result = parts.length === 1 ? _.range(parts[0]) : _.range(parts[0], parts[1], parts[2] || 1);
document.getElementById('rangeResult').textContent = '[' + result.join(', ') + ']';
}
updateCase();
updateSlug();
</script>
</body>
</html>What’s Next
You’ve completed the full Lodash track. Here’s where to go from here:
| Step | Topic | Why |
|---|---|---|
| JavaScript Fundamentals | Review core JavaScript concepts | Strengthen your foundation |
| Axios HTTP Requests | Learn HTTP request handling with Axios | Combine with Lodash for API data pipelines |
| Node.js | Server-side JavaScript | Apply Lodash in backend data processing |
| React | Frontend framework | Use Lodash for state transformations |
| JSON Data | Data interchange format | Essential for API and config handling |
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro — where Lodash powers everything from file signature scanning pipelines to configuration management.
What’s Next
Congratulations on completing this Lodash Utilities tutorial! Here’s where to go from here:
- Practice daily — Consistency is more important than long study sessions
- Build a project — Apply what you learned by building something real
- Explore related topics — Check out other tutorials in the same category
- Join the community — Discuss with other learners and share your progress
Remember: every expert was once a beginner. Keep coding!
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro