#JavaScript Libraries
JavaScript libraries are pre-written code collections that provide encapsulated specific functionalities, simplifying development and improving efficiency. In modern JavaScript development, using libraries wisely can greatly reduce repetitive work and improve code quality.
#What is a JavaScript Library
A JavaScript library is a set of pre-written JavaScript code that encapsulates specific functionality for developers to reuse in projects. Libraries typically solve problems in specific domains, such as DOM manipulation, animation effects, data processing, etc.
#Library Characteristics
- Single Purpose: Focuses on solving specific problems
- Reusability: Can be used across multiple projects
- Encapsulation: Hides implementation details, provides simple interfaces
- Standardization: Follows industry standards and best practices
- Community Support: Usually maintained by active communities
#Common JavaScript Libraries
#1. Lodash - Utility Library
Lodash is a modern JavaScript utility library that provides processing methods for arrays, objects, strings, and other data types.
// Install: npm install lodash
// Import
const _ = require('lodash');
// Array operations
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Chunk
console.log(_.chunk(numbers, 3));
// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
// Unique
const duplicates = [1, 2, 2, 3, 3, 4, 5, 5];
console.log(_.uniq(duplicates)); // [1, 2, 3, 4, 5]
// Difference
const array1 = [1, 2, 3];
const array2 = [2, 3, 4];
console.log(_.difference(array1, array2)); // [1]
// Intersection
console.log(_.intersection(array1, array2)); // [2, 3]
// Union
console.log(_.union(array1, array2)); // [1, 2, 3, 4]
// Object operations
const users = [
{ name: "John", age: 25, active: true },
{ name: "Jane", age: 30, active: false },
{ name: "Bob", age: 35, active: true }
];
// Filter
console.log(_.filter(users, { active: true }));
// Find
console.log(_.find(users, { age: 30 })); // { name: "Jane", age: 30, active: false }
// Group by
console.log(_.groupBy(users, "active"));
// Sort
console.log(_.orderBy(users, ["age"], ["desc"]));
// Deep clone
const original = {
name: "John",
profile: {
age: 25,
hobbies: ["reading", "swimming"]
}
};
const cloned = _.cloneDeep(original);
cloned.profile.age = 26;
console.log(original.profile.age); // 25
console.log(cloned.profile.age); // 26
// Debounce
const debouncedFunction = _.debounce(() => {
console.log("Debounced function executed");
}, 300);
// Throttle
const throttledFunction = _.throttle(() => {
console.log("Throttled function executed");
}, 1000);
// String operations
console.log(_.camelCase("hello world")); // "helloWorld"
console.log(_.kebabCase("hello world")); // "hello-world"
console.log(_.startCase("hello world")); // "Hello World"
console.log(_.capitalize("hello world")); // "Hello world"#2. Day.js / Moment.js - Date Libraries
Day.js is a lightweight date handling library (Moment.js alternative).
// Install: npm install dayjs
const dayjs = require('dayjs');
// Create date
const now = dayjs();
const specificDate = dayjs("2024-01-15");
const fromString = dayjs("2024-01-15 10:30:00");
// Format date
console.log(now.format("YYYY-MM-DD")); // "2024-01-15"
console.log(now.format("YYYY/MM/DD HH:mm:ss")); // "2024/01/15 10:30:00"
// Date calculation
console.log(now.add(7, "day").format("YYYY-MM-DD")); // 7 days later
console.log(now.subtract(1, "month").format("YYYY-MM-DD")); // 1 month ago
console.log(now.startOf("month").format("YYYY-MM-DD")); // Start of month
console.log(now.endOf("month").format("YYYY-MM-DD")); // End of month
// Date comparison
const date1 = dayjs("2024-01-15");
const date2 = dayjs("2024-01-20");
console.log(date1.isBefore(date2)); // true
console.log(date1.isAfter(date2)); // false
console.log(date1.isSame(date2, "year")); // true
// Date difference
console.log(date2.diff(date1, "day")); // 5
console.log(date2.diff(date1, "hour")); // 120
// Relative time (requires plugin)
// const relativeTime = require('dayjs/plugin/relativeTime');
// dayjs.extend(relativeTime);
// console.log(dayjs().subtract(1, "hour").fromNow()); // "1 hour ago"#3. Axios - HTTP Client Library
Axios is a Promise-based HTTP client for browsers and Node.js.
// Install: npm install axios
const axios = require('axios');
// Basic GET request
axios.get('https://api.github.com/users/octocat')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
// GET with parameters
axios.get('https://api.github.com/search/repositories', {
params: {
q: 'javascript',
sort: 'stars',
order: 'desc'
}
}).then(response => {
console.log(response.data.items);
});
// POST request
axios.post('https://jsonplaceholder.typicode.com/posts', {
title: 'foo',
body: 'bar',
userId: 1
}).then(response => {
console.log(response.data);
});
// Concurrent requests
Promise.all([
axios.get('https://api.github.com/users/octocat'),
axios.get('https://api.github.com/users/torvalds')
]).then(([octocat, torvalds]) => {
console.log('Octocat:', octocat.data.name);
console.log('Torvalds:', torvalds.data.name);
});
// Create instance
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000,
headers: {
'Authorization': 'Bearer your-token',
'Content-Type': 'application/json'
}
});
// Request interceptor
api.interceptors.request.use(
config => {
console.log('Sending request:', config.url);
return config;
},
error => {
return Promise.reject(error);
}
);
// Response interceptor
api.interceptors.response.use(
response => {
console.log('Received response:', response.status);
return response;
},
error => {
if (error.response && error.response.status === 401) {
console.log('Unauthorized, please login again');
}
return Promise.reject(error);
}
);#4. D3.js - Data Visualization Library
D3.js is a powerful data visualization library for creating dynamic, interactive data charts.
// Basic D3.js bar chart example
// Include: <script src="https://d3js.org/d3.v7.min.js"></script>
// Prepare data
const data = [
{ name: "Apple", value: 30 },
{ name: "Banana", value: 20 },
{ name: "Orange", value: 25 },
{ name: "Grape", value: 15 },
{ name: "Strawberry", value: 10 }
];
// Set chart dimensions and margins
const margin = { top: 20, right: 30, bottom: 40, left: 40 };
const width = 500 - margin.left - margin.right;
const height = 300 - margin.top - margin.bottom;
// Create SVG container
const svg = d3.select("#chart")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
// Set scales
const x = d3.scaleBand()
.domain(data.map(d => d.name))
.range([0, width])
.padding(0.1);
const y = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)])
.range([height, 0]);
// Create bars
svg.selectAll(".bar")
.data(data)
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", d => x(d.name))
.attr("width", x.bandwidth())
.attr("y", d => y(d.value))
.attr("height", d => height - y(d.value));
// Add axes
svg.append("g")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom(x));
svg.append("g")
.call(d3.axisLeft(y));#5. Three.js - 3D Graphics Library
Three.js is a WebGL-based 3D graphics library for creating and displaying 3D content in browsers.
// Basic Three.js example
// Include: <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
// Create scene
const scene = new THREE.Scene();
// Create camera
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// Create renderer
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Create cube
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// Create light
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(1, 1, 1).normalize();
scene.add(light);
// Animation loop
function animate() {
requestAnimationFrame(animate);
// Rotate cube
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
// Window resize handling
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});#Library Selection and Usage
#Selection Criteria
// Library evaluation criteria
const libraryEvaluationCriteria = {
// 1. Functionality
features: [
"Does it meet project requirements",
"Is functionality complete",
"How extensible is it"
],
// 2. Performance
performance: [
"Load speed",
"Runtime efficiency",
"Memory usage"
],
// 3. Stability
stability: [
"Version update frequency",
"Bug fix speed",
"Long-term maintenance"
],
// 4. Community Support
community: [
"Documentation quality",
"Community activity",
"Third-party resources"
],
// 5. Learning Curve
learningCurve: [
"Is API design intuitive",
"Is documentation clear",
"Are examples abundant"
],
// 6. Size
size: [
"File size",
"Supports tree shaking",
"On-demand loading"
]
};#On-demand Loading
// Lodash on-demand loading
// Install: npm install lodash
const chunk = require('lodash/chunk');
const uniq = require('lodash/uniq');
const debounce = require('lodash/debounce');
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(chunk(numbers, 3)); // [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
console.log(uniq([1, 2, 2, 3, 3, 4])); // [1, 2, 3, 4]
// Debounce function
const debouncedSearch = debounce((query) => {
console.log("Search:", query);
}, 300);
// D3.js on-demand loading
// Install: npm install d3-selection d3-scale d3-axis
// import { select } from 'd3-selection';
// import { scaleLinear, scaleBand } from 'd3-scale';
// import { axisBottom, axisLeft } from 'd3-axis';#Custom Utility Library
#Creating Your Own Library
// utils.js - Custom utility library
class CustomUtils {
// Array utilities
static array = {
// Chunk array
chunk(array, size) {
const chunks = [];
for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}
return chunks;
},
// Unique array
unique(array) {
return [...new Set(array)];
},
// Array difference
difference(array, ...values) {
const flatValues = values.flat();
return array.filter(item => !flatValues.includes(item));
},
// Array intersection
intersection(array, ...values) {
const flatValues = values.flat();
return array.filter(item => flatValues.includes(item));
},
// Shuffle array
shuffle(array) {
const result = [...array];
for (let i = result.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[result[i], result[j]] = [result[j], result[i]];
}
return result;
}
};
// Object utilities
static object = {
// Deep clone
deepClone(obj) {
if (obj === null || typeof obj !== "object") return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof Array) return obj.map(item => this.deepClone(item));
if (obj instanceof Object) {
const clonedObj = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
clonedObj[key] = this.deepClone(obj[key]);
}
}
return clonedObj;
}
},
// Object map
map(obj, fn) {
const result = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
result[key] = fn(obj[key], key);
}
}
return result;
},
// Object filter
filter(obj, fn) {
const result = {};
for (const key in obj) {
if (obj.hasOwnProperty(key) && fn(obj[key], key)) {
result[key] = obj[key];
}
}
return result;
}
};
// String utilities
static string = {
// Camel case
camelCase(str) {
return str.replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : '');
},
// Kebab case
kebabCase(str) {
return str.replace(/([A-Z])/g, '-$1')
.replace(/[-_\s]+/g, '-')
.toLowerCase();
},
// Capitalize
capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
},
// Format string
format(str, ...args) {
return str.replace(/{(\d+)}/g, (match, index) => {
return typeof args[index] !== 'undefined' ? args[index] : match;
});
}
};
// Number utilities
static number = {
// Precise addition
add(a, b, precision = 10) {
return parseFloat((a + b).toFixed(precision));
},
// Format number
format(num, options = {}) {
const {
decimals = 2,
thousandSeparator = ",",
decimalSeparator = "."
} = options;
const fixed = num.toFixed(decimals);
const [integer, decimal] = fixed.split(".");
const formattedInteger = integer.replace(
/\B(?=(\d{3})+(?!\d))/g,
thousandSeparator
);
return decimal
? formattedInteger + decimalSeparator + decimal
: formattedInteger;
}
};
// Function utilities
static function = {
// Debounce
debounce(func, wait, immediate = false) {
let timeout;
return function executedFunction(...args) {
const later = () => {
timeout = null;
if (!immediate) func.apply(this, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(this, args);
};
},
// Throttle
throttle(func, limit) {
let inThrottle;
return function() {
const args = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
},
// Memoize
memoize(func, resolver) {
const memoized = function(...args) {
const key = resolver ? resolver.apply(this, args) : args[0];
if (memoized.cache.has(key)) {
return memoized.cache.get(key);
}
const result = func.apply(this, args);
memoized.cache.set(key, result);
return result;
};
memoized.cache = new Map();
return memoized;
}
};
// Date utilities
static date = {
// Format date
format(date, format = "YYYY-MM-DD") {
const d = new Date(date);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
const hours = String(d.getHours()).padStart(2, "0");
const minutes = String(d.getMinutes()).padStart(2, "0");
const seconds = String(d.getSeconds()).padStart(2, "0");
return format
.replace("YYYY", year)
.replace("MM", month)
.replace("DD", day)
.replace("HH", hours)
.replace("mm", minutes)
.replace("ss", seconds);
},
// Days between two dates
daysBetween(date1, date2) {
const oneDay = 24 * 60 * 60 * 1000;
const firstDate = new Date(date1);
const secondDate = new Date(date2);
return Math.round(Math.abs((firstDate - secondDate) / oneDay));
},
// Relative time
relativeTime(date) {
const now = new Date();
const target = new Date(date);
const diffInSeconds = Math.floor((now - target) / 1000);
if (diffInSeconds < 60) {
return "just now";
} else if (diffInSeconds < 3600) {
return `${Math.floor(diffInSeconds / 60)} minutes ago`;
} else if (diffInSeconds < 86400) {
return `${Math.floor(diffInSeconds / 3600)} hours ago`;
} else if (diffInSeconds < 2592000) {
return `${Math.floor(diffInSeconds / 86400)} days ago`;
} else {
return this.format(date);
}
}
};
}
// Usage examples
console.log(CustomUtils.array.chunk([1, 2, 3, 4, 5, 6, 7, 8], 3));
console.log(CustomUtils.array.unique([1, 2, 2, 3, 3, 4]));
console.log(CustomUtils.object.deepClone({ a: 1, b: { c: 2 } }));
console.log(CustomUtils.string.camelCase("hello-world"));
console.log(CustomUtils.number.format(1234567.89));
console.log(CustomUtils.date.format(new Date(), "YYYY/MM/DD HH:mm:ss"));#Library Management and Optimization
#Package Management
{
"name": "my-project",
"version": "1.0.0",
"description": "My JavaScript project",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"build": "webpack --mode production",
"test": "jest"
},
"dependencies": {
"axios": "^1.6.0",
"lodash": "^4.17.21"
},
"devDependencies": {
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"jest": "^29.7.0"
},
"engines": {
"node": ">=14.0.0"
}
}#Performance Optimization
// Tree Shaking configuration (webpack.config.js)
module.exports = {
mode: 'production',
optimization: {
usedExports: true,
sideEffects: false
}
};
// Code splitting - Dynamic imports
async function loadLodash() {
const { chunk } = await import('lodash/chunk');
return chunk([1, 2, 3, 4, 5], 2);
}
// Preload
const importantLibrary = import('important-library');
// Lazy loading
document.getElementById('button').addEventListener('click', async () => {
const { default: Chart } = await import('chart.js');
// Use chart library
});
// Bundle analysis
// Install: npm install --save-dev webpack-bundle-analyzer
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
};#Practical Examples
#Comprehensive Utility Library
// comprehensive-utils.js
class ComprehensiveUtils {
// HTTP utilities
static http = {
async request(url, options = {}) {
const defaultOptions = {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
};
const config = { ...defaultOptions, ...options };
try {
const response = await fetch(url, config);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
return await response.json();
}
return await response.text();
} catch (error) {
throw new Error(`Request failed: ${error.message}`);
}
},
get(url, options = {}) {
return this.request(url, { ...options, method: 'GET' });
},
post(url, data, options = {}) {
return this.request(url, {
...options,
method: 'POST',
body: JSON.stringify(data)
});
}
};
// Storage utilities
static storage = {
local: {
set(key, value) {
try {
localStorage.setItem(key, JSON.stringify(value));
return true;
} catch (error) {
console.error('Local storage set failed:', error);
return false;
}
},
get(key, defaultValue = null) {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : defaultValue;
} catch (error) {
console.error('Local storage get failed:', error);
return defaultValue;
}
},
remove(key) {
try {
localStorage.removeItem(key);
return true;
} catch (error) {
console.error('Local storage remove failed:', error);
return false;
}
}
}
};
// Validation utilities
static validation = {
isEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
},
isUrl(url) {
try {
new URL(url);
return true;
} catch {
return false;
}
},
isNumber(value) {
return !isNaN(parseFloat(value)) && isFinite(value);
}
};
// Format utilities
static format = {
currency(amount, currency = "USD", locale = "en-US") {
return new Intl.NumberFormat(locale, {
style: "currency",
currency: currency
}).format(amount);
},
bytes(bytes) {
if (bytes === 0) return "0 Bytes";
const k = 1024;
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
}
};
// Device detection
static device = {
isMobile() {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
},
isIOS() {
return /iPad|iPhone|iPod/.test(navigator.userAgent);
},
isAndroid() {
return /Android/.test(navigator.userAgent);
}
};
}
// Usage examples
ComprehensiveUtils.storage.local.set('user', { name: 'John', age: 25 });
console.log(ComprehensiveUtils.storage.local.get('user'));
console.log(ComprehensiveUtils.validation.isEmail('test@example.com')); // true
console.log(ComprehensiveUtils.format.currency(1234.56)); // "$1,234.56"
console.log(ComprehensiveUtils.format.bytes(1024)); // "1 KB"
console.log(ComprehensiveUtils.device.isMobile());#Summary
Key points of JavaScript libraries:
- Basic Concepts: Pre-written code collections that solve specific problems
- Common Libraries: Lodash, Day.js, Axios, D3.js, Three.js, etc.
- Selection Criteria: Functionality, performance, stability, community support, etc.
- Usage Methods: npm installation, on-demand loading, Tree Shaking optimization
- Custom Libraries: Create your own utility library to meet specific needs
- Management Optimization: Package management, performance optimization, code splitting
- Practical Applications: Comprehensive utility libraries, project scaffolding, etc.
Using JavaScript libraries wisely can greatly improve development efficiency, but be careful not to over-rely on them. Choose appropriate libraries based on project requirements. In the next chapter, we will learn about JavaScript learning resources.