jQuery provides a comprehensive set of utility functions for common programming tasks including iteration, type checking, data manipulation, and object operations. These utilities are available as static methods on the jQuery object and provide cross-browser compatibility.
interface JQueryStatic {
// Iterate over arrays and objects
each<T>(array: T[], callback: (this: T, indexInArray: number, valueOfElement: T) => void | false): T[];
each<T>(object: JQuery.PlainObject<T>, callback: (this: T, propertyName: string, valueOfProperty: T) => void | false): JQuery.PlainObject<T>;
// Transform arrays and objects
map<T, TReturn>(array: T[], callback: (this: Window, elementOfArray: T, indexInArray: number) => TReturn | null | undefined): TReturn[];
map<T, TReturn>(object: JQuery.PlainObject<T>, callback: (this: Window, propertyOfObject: T, key: string) => TReturn | null | undefined): TReturn[];
// Filter arrays
grep<T>(array: T[], func: (elementOfArray: T, indexInArray: number) => boolean, invert?: boolean): T[];
// Merge arrays
merge<T>(first: T[], second: T[]): T[];
// Create arrays from array-like objects
makeArray(obj: any): any[];
// Check if value is in array
inArray<T>(value: T, array: T[], fromIndex?: number): number;
// Remove duplicates
unique<T extends Element>(array: T[]): T[];
}// Iterate over arrays
const numbers = [1, 2, 3, 4, 5];
$.each(numbers, function(index, value) {
console.log(`Index ${index}: ${value}`);
});
// Iterate over objects
const person = { name: 'John', age: 30, city: 'New York' };
$.each(person, function(key, value) {
console.log(`${key}: ${value}`);
});
// Early termination by returning false
$.each(numbers, function(index, value) {
if (value === 3) return false; // Stop iteration
console.log(value);
}); // Prints: 1, 2
// Transform arrays with map
const doubled = $.map(numbers, function(value, index) {
return value * 2;
});
console.log(doubled); // [2, 4, 6, 8, 10]
// Transform objects with map
const personValues = $.map(person, function(value, key) {
return `${key}: ${value}`;
});
console.log(personValues); // ['name: John', 'age: 30', 'city: New York']
// Filter arrays with grep
const evenNumbers = $.grep(numbers, function(value, index) {
return value % 2 === 0;
});
console.log(evenNumbers); // [2, 4]
// Invert filter (get odd numbers)
const oddNumbers = $.grep(numbers, function(value) {
return value % 2 === 0;
}, true); // invert = true
console.log(oddNumbers); // [1, 3, 5]
// Merge arrays
const moreNumbers = [6, 7, 8];
const allNumbers = $.merge(numbers.slice(), moreNumbers); // Use slice() to avoid modifying original
console.log(allNumbers); // [1, 2, 3, 4, 5, 6, 7, 8]
// Convert array-like to array
const nodeList = document.querySelectorAll('div');
const divArray = $.makeArray(nodeList);
console.log(Array.isArray(divArray)); // true
// Check if value exists in array
const index = $.inArray(3, numbers);
console.log(index); // 2 (index of value 3)
// Remove duplicates from DOM elements array
const elements = $.unique($('div, span, div').toArray());interface JQueryStatic {
// Type checking functions
isArray(obj: any): obj is any[];
isEmptyObject(obj: any): boolean;
isFunction(obj: any): obj is Function;
isNumeric(obj: any): boolean;
isPlainObject(obj: any): obj is JQuery.PlainObject;
isWindow(obj: any): obj is Window;
isXMLDoc(node: Node): boolean;
// Get type string
type(obj: any): string;
}// Array detection
console.log($.isArray([])); // true
console.log($.isArray({})); // false
console.log($.isArray('string')); // false
// Function detection
console.log($.isFunction(function() {})); // true
console.log($.isFunction(() => {})); // true
console.log($.isFunction('string')); // false
// Numeric detection
console.log($.isNumeric(123)); // true
console.log($.isNumeric('123')); // true
console.log($.isNumeric('123px')); // false
console.log($.isNumeric(NaN)); // false
// Plain object detection (excludes DOM elements, functions, etc.)
console.log($.isPlainObject({})); // true
console.log($.isPlainObject({ key: 'value' })); // true
console.log($.isPlainObject(document.createElement('div'))); // false
console.log($.isPlainObject([])); // false
// Empty object detection
console.log($.isEmptyObject({})); // true
console.log($.isEmptyObject({ a: 1 })); // false
console.log($.isEmptyObject([])); // true (arrays are objects)
// Window detection
console.log($.isWindow(window)); // true
console.log($.isWindow(document)); // false
// XML document detection
console.log($.isXMLDoc(document)); // false (HTML document)
// Get detailed type information
console.log($.type(123)); // 'number'
console.log($.type('string')); // 'string'
console.log($.type([])); // 'array'
console.log($.type({})); // 'object'
console.log($.type(null)); // 'null'
console.log($.type(undefined)); // 'undefined'
console.log($.type(/regex/)); // 'regexp'
console.log($.type(new Date())); // 'date'
// Type-safe utility function
function processValue(value: any) {
if ($.isArray(value)) {
console.log('Processing array with', value.length, 'items');
} else if ($.isPlainObject(value)) {
const keys = Object.keys(value);
console.log('Processing object with keys:', keys);
} else if ($.isFunction(value)) {
console.log('Processing function');
value(); // Safe to call
} else if ($.isNumeric(value)) {
console.log('Processing number:', parseFloat(value));
} else {
console.log('Processing other type:', $.type(value));
}
}interface JQueryStatic {
// Extend objects (merge properties)
extend<T>(target: T): T;
extend<T, U>(target: T, object1: U): T & U;
extend<T, U, V>(target: T, object1: U, object2: V): T & U & V;
extend<T, U, V, W>(target: T, object1: U, object2: V, object3: W): T & U & V & W;
extend(target: any, ...objects: any[]): any;
// Deep extend
extend<T>(deep: true, target: T): T;
extend<T, U>(deep: true, target: T, object1: U): T & U;
extend<T, U, V>(deep: true, target: T, object1: U, object2: V): T & U & V;
extend(deep: boolean, target: any, ...objects: any[]): any;
// Global evaluation
globalEval(code: string): void;
globalEval(code: string, options: { nonce?: string; }): void;
// No conflict mode
noConflict(removeAll?: boolean): JQueryStatic;
// Parse data formats
parseHTML(data: string, context?: Document, keepScripts?: boolean): Element[];
parseJSON(json: string): any;
parseXML(data: string): Document;
// URL parameter serialization
param(obj: any, traditional?: boolean): string;
}// Shallow extend (merge objects)
const defaults = { color: 'red', size: 'medium', visible: true };
const options = { size: 'large', position: 'top' };
const config = $.extend({}, defaults, options);
console.log(config);
// { color: 'red', size: 'large', visible: true, position: 'top' }
// Deep extend (recursive merge)
const defaultConfig = {
ui: { theme: 'light', colors: { primary: 'blue', secondary: 'gray' } },
api: { timeout: 5000, retries: 3 }
};
const userConfig = {
ui: { colors: { primary: 'green' } },
api: { timeout: 10000 }
};
const merged = $.extend(true, {}, defaultConfig, userConfig);
console.log(merged);
// {
// ui: { theme: 'light', colors: { primary: 'green', secondary: 'gray' } },
// api: { timeout: 10000, retries: 3 }
// }
// Extend existing object
const settings = { debug: false };
$.extend(settings, { debug: true, verbose: true });
console.log(settings); // { debug: true, verbose: true }
// Parse JSON safely
function safeParseJSON(jsonString: string) {
try {
return $.parseJSON(jsonString);
} catch (e) {
console.error('Invalid JSON:', e);
return null;
}
}
const data = safeParseJSON('{"name": "John", "age": 30}');
console.log(data); // { name: 'John', age: 30 }
// Parse HTML strings
const htmlString = '<div class="item">Content</div><span>More content</span>';
const elements = $.parseHTML(htmlString);
console.log(elements.length); // 2 elements
// Parse XML
const xmlString = '<root><item id="1">Value</item></root>';
const xmlDoc = $.parseXML(xmlString);
console.log(xmlDoc.documentElement.tagName); // 'root'
// Serialize objects to URL parameters
const formData = {
name: 'John Doe',
email: 'john@example.com',
preferences: ['email', 'sms'],
settings: { theme: 'dark', lang: 'en' }
};
const queryString = $.param(formData);
console.log(queryString);
// 'name=John+Doe&email=john%40example.com&preferences%5B%5D=email&preferences%5B%5D=sms&settings%5Btheme%5D=dark&settings%5Blang%5D=en'
// Traditional parameter serialization
const traditionalParams = $.param(formData, true);
console.log(traditionalParams);// Trim whitespace (for older browser compatibility)
interface JQueryStatic {
trim(str: string): string;
}
// String utilities
$.trim(' hello world '); // 'hello world'
// Custom string utilities (not built-in jQuery, but commonly added)
$.extend($, {
// Capitalize first letter
capitalize: function(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
},
// Convert to camelCase
camelCase: function(str: string): string {
return str.replace(/-([a-z])/g, function(match, letter) {
return letter.toUpperCase();
});
},
// Escape HTML entities
escapeHtml: function(unsafe: string): string {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
});
// Usage of custom utilities
console.log($.capitalize('hello world')); // 'Hello world'
console.log($.camelCase('background-color')); // 'backgroundColor'
console.log($.escapeHtml('<script>alert("xss")</script>'));interface JQueryStatic {
// Create a function that only executes once
proxy(func: Function, context: any): Function;
proxy(context: any, name: string): Function;
// No operation function
noop(): void;
}
// Function utilities examples
const obj = {
name: 'Example',
greet: function() {
console.log('Hello from ' + this.name);
}
};
// Proxy function to maintain context
const boundGreet = $.proxy(obj.greet, obj);
boundGreet(); // 'Hello from Example'
// Proxy by method name
const boundGreet2 = $.proxy(obj, 'greet');
boundGreet2(); // 'Hello from Example'
// Use proxy for event handlers
$('#button').on('click', $.proxy(obj.greet, obj));
// No-op function for default callbacks
function makeRequest(callback = $.noop) {
// Do some work...
callback(); // Safe to call even if no callback provided
}
// Custom function utilities
$.extend($, {
// Debounce function
debounce: function<T extends Function>(func: T, wait: number): T {
let timeout: number;
return function(this: any, ...args: any[]) {
clearTimeout(timeout);
timeout = window.setTimeout(() => func.apply(this, args), wait);
} as any;
},
// Throttle function
throttle: function<T extends Function>(func: T, limit: number): T {
let inThrottle: boolean;
return function(this: any, ...args: any[]) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
} as any;
},
// Once function (execute only once)
once: function<T extends Function>(func: T): T {
let called = false;
let result: any;
return function(this: any, ...args: any[]) {
if (!called) {
called = true;
result = func.apply(this, args);
}
return result;
} as any;
}
});
// Usage of custom function utilities
const debouncedResize = $.debounce(function() {
console.log('Window resized');
}, 250);
$(window).on('resize', debouncedResize);
const throttledScroll = $.throttle(function() {
console.log('Scrolling...');
}, 100);
$(window).on('scroll', throttledScroll);
const initOnce = $.once(function() {
console.log('This will only log once');
// Expensive initialization code
});
initOnce(); // Logs message
initOnce(); // Does nothing// Custom collection utilities
$.extend($, {
// Group array by property
groupBy: function<T>(array: T[], property: keyof T | ((item: T) => string)): { [key: string]: T[] } {
const groups: { [key: string]: T[] } = {};
$.each(array, function(index, item) {
const key = typeof property === 'function' ? property(item) : String(item[property]);
if (!groups[key]) groups[key] = [];
groups[key].push(item);
});
return groups;
},
// Flatten nested arrays
flatten: function<T>(array: any[]): T[] {
const result: T[] = [];
$.each(array, function(index, item) {
if ($.isArray(item)) {
result.push(...$.flatten(item));
} else {
result.push(item);
}
});
return result;
},
// Get unique values from array
uniqueValues: function<T>(array: T[]): T[] {
const seen = new Set<T>();
return $.grep(array, function(item) {
if (seen.has(item)) {
return false;
} else {
seen.add(item);
return true;
}
});
},
// Chunk array into smaller arrays
chunk: function<T>(array: T[], size: number): T[][] {
const chunks: T[][] = [];
for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}
return chunks;
},
// Find intersection of arrays
intersect: function<T>(...arrays: T[][]): T[] {
if (arrays.length === 0) return [];
if (arrays.length === 1) return arrays[0].slice();
return arrays[0].filter(item =>
arrays.slice(1).every(array =>
$.inArray(item, array) !== -1
)
);
}
});
// Usage examples
const users = [
{ name: 'John', department: 'IT', age: 30 },
{ name: 'Jane', department: 'HR', age: 25 },
{ name: 'Bob', department: 'IT', age: 35 },
{ name: 'Alice', department: 'HR', age: 28 }
];
// Group users by department
const grouped = $.groupBy(users, 'department');
console.log(grouped);
// { IT: [John, Bob], HR: [Jane, Alice] }
// Group by computed property
const ageGroups = $.groupBy(users, (user) => user.age >= 30 ? 'senior' : 'junior');
console.log(ageGroups);
// { senior: [John, Bob], junior: [Jane, Alice] }
// Flatten nested arrays
const nested = [[1, 2], [3, [4, 5]], 6];
const flattened = $.flatten(nested);
console.log(flattened); // [1, 2, 3, 4, 5, 6]
// Get unique values
const numbers = [1, 2, 2, 3, 3, 3, 4];
const unique = $.uniqueValues(numbers);
console.log(unique); // [1, 2, 3, 4]
// Chunk array
const items = [1, 2, 3, 4, 5, 6, 7, 8];
const chunks = $.chunk(items, 3);
console.log(chunks); // [[1, 2, 3], [4, 5, 6], [7, 8]]
// Find intersection
const arr1 = [1, 2, 3, 4];
const arr2 = [3, 4, 5, 6];
const arr3 = [4, 5, 6, 7];
const intersection = $.intersect(arr1, arr2, arr3);
console.log(intersection); // [4]// Performance measurement utilities
$.extend($, {
// Simple performance timer
timer: function(name: string) {
const start = performance.now();
return {
end: function() {
const duration = performance.now() - start;
console.log(`${name}: ${duration.toFixed(2)}ms`);
return duration;
}
};
},
// Memoization utility
memoize: function<T extends Function>(func: T): T {
const cache = new Map();
return function(this: any, ...args: any[]) {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = func.apply(this, args);
cache.set(key, result);
return result;
} as any;
},
// Batch DOM operations
batch: function(operations: Array<() => void>) {
// Batch operations to minimize reflows
requestAnimationFrame(() => {
$.each(operations, function(index, operation) {
operation();
});
});
}
});
// Usage examples
const timer = $.timer('Data processing');
// ... do some work ...
timer.end(); // Logs: "Data processing: 42.15ms"
// Memoized expensive function
const expensiveFunction = $.memoize(function(n: number): number {
console.log('Computing for', n);
let result = 0;
for (let i = 0; i < n * 1000000; i++) {
result += Math.random();
}
return result;
});
expensiveFunction(100); // Computes result
expensiveFunction(100); // Returns cached result
// Batch DOM operations
$.batch([
() => $('#element1').css('width', '200px'),
() => $('#element2').css('height', '100px'),
() => $('#element3').addClass('active')
]);// Validation helper utilities
$.extend($, {
// Email validation
isValidEmail: function(email: string): boolean {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
},
// URL validation
isValidUrl: function(url: string): boolean {
try {
new URL(url);
return true;
} catch {
return false;
}
},
// Date validation
isValidDate: function(date: any): boolean {
return date instanceof Date && !isNaN(date.getTime());
},
// Required field validation
isRequired: function(value: any): boolean {
if (value == null) return false;
if (typeof value === 'string') return value.trim().length > 0;
if ($.isArray(value)) return value.length > 0;
return true;
},
// Range validation
inRange: function(value: number, min: number, max: number): boolean {
return $.isNumeric(value) && value >= min && value <= max;
}
});
// Form validation example
function validateForm(data: any): { valid: boolean; errors: string[] } {
const errors: string[] = [];
if (!$.isRequired(data.name)) {
errors.push('Name is required');
}
if (!$.isRequired(data.email)) {
errors.push('Email is required');
} else if (!$.isValidEmail(data.email)) {
errors.push('Email format is invalid');
}
if (data.age !== undefined && !$.inRange(data.age, 0, 120)) {
errors.push('Age must be between 0 and 120');
}
if (data.website && !$.isValidUrl(data.website)) {
errors.push('Website URL is invalid');
}
return {
valid: errors.length === 0,
errors: errors
};
}
// Usage
const formData = {
name: 'John Doe',
email: 'invalid-email',
age: 25,
website: 'https://example.com'
};
const validation = validateForm(formData);
if (!validation.valid) {
console.log('Validation errors:', validation.errors);
}The utility functions provide a comprehensive toolkit for common programming tasks with cross-browser compatibility and TypeScript support. These utilities extend jQuery's capabilities beyond DOM manipulation to general-purpose programming tasks, making it a complete solution for web development.