JavaScript 封装是构建可维护、可重用代码的核心技术。以下是高级封装方法的全面指南,涵盖多种场景和最佳实践。
一、基础封装进阶
1. IIFE (立即调用函数表达式)
const counter = (() => {
let count = 0;
return {
increment() {
return ++count;
},
decrement() {
return --count;
},
get value() {
return count;
}
};
})();
counter.increment(); // 1
counter.value; // 1
2. 模块模式
const apiService = (function() {
const baseUrl = 'https://api.example.com';
const request = async (endpoint, options) => {
try {
const response = await fetch(`${baseUrl}${endpoint}`, options);
return await response.json();
} catch (error) {
console.error('API Error:', error);
throw error;
}
};
return {
getUsers: () => request('/users'),
createUser: (userData) => request('/users', {
method: 'POST',
body: JSON.stringify(userData)
})
};
})();
二、面向对象高级封装
1. 类与私有字段
class Person {
#age; // 私有字段
constructor(name, age) {
this.name = name;
this.#age = age;
}
get age() {
return this.#age;
}
#calculateBirthYear() { // 私有方法
return new Date().getFullYear() - this.#age;
}
get birthYear() {
return this.#calculateBirthYear();
}
}
const john = new Person('John', 30);
john.age; // 30
john.birthYear; // 1993
// john.#calculateBirthYear(); // 报错
2. 混入模式 (Mixins)
const Loggable = (Base) => class extends Base {
log(message) {
console.log(`[${this.constructor.name}] ${message}`);
}
};
const Serializable = (Base) => class extends Base {
serialize() {
return JSON.stringify(this);
}
};
class User {
constructor(name) {
this.name = name;
}
}
const EnhancedUser = Loggable(Serializable(User));
const user = new EnhancedUser('Alice');
user.log('User created'); // "[EnhancedUser] User created"
user.serialize(); // "{"name":"Alice"}"
三、函数式编程封装
1. 高阶函数
const withRetry = (fn, maxRetries = 3) => async (...args) => {
let lastError;
for (let i = 0; i maxRetries; i++) {
try {
return await fn(...args);
} catch (error) {
lastError = error;
console.log(`Attempt ${i + 1} failed. Retrying...`);
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
throw lastError;
};
// 使用示例
const fetchWithRetry = withRetry(fetch);
fetchWithRetry('https://api.example.com/data');
2. 柯里化 (Currying)
const curry = (fn) => {
const arity = fn.length;
return function curried(...args) {
if (args.length >= arity) {
return fn.apply(this, args);
} else {
return (...moreArgs) => curried.apply(this, args.concat(moreArgs));
}
};
};
// 使用示例
const add = (a, b, c) => a + b + c;
const curriedAdd = curry(add);
curriedAdd(1)(2)(3); // 6
四、现代 JavaScript 封装技术
1. Proxy 封装
const createValidator = (target, validator) => {
return new Proxy(target, {
set(obj, prop, value) {
if (validator[prop] && !validator[prop](value)) {
throw new Error(`Invalid value for ${prop}`);
}
obj[prop] = value;
return true;
}
});
};
// 使用示例
const personValidator = {
name: val => typeof val === 'string' && val.length > 0,
age: val => Number.isInteger(val) && val >= 0
};
const person = createValidator({}, personValidator);
person.name = 'John'; // 成功
person.age = '30'; // 抛出错误
2. 响应式封装
const reactive = (obj) => {
const handlers = {
get(target, prop) {
track(target, prop);
return Reflect.get(...arguments);
},
set(target, prop, value) {
Reflect.set(...arguments);
trigger(target, prop);
return true;
}
};
const trackedProps = new Set();
const track = (target, prop) => {
trackedProps.add(prop);
};
const trigger = (target, prop) => {
if (trackedProps.has(prop)) {
console.log(`${prop} changed to ${target[prop]}`);
}
};
return new Proxy(obj, handlers);
};
// 使用示例
const state = reactive({ count: 0 });
state.count; // 跟踪访问
state.count = 1; // 输出: "count changed to 1"
五、性能优化封装
1. 记忆化 (Memoization)
const memoize = (fn) => {
const cache = new Map();
return (...args) => {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn(...args);
cache.set(key, result);
return result;
};
};
// 使用示例
const fibonacci = memoize((n) => {
if (n 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
});
fibonacci(50); // 快速计算
2. 防抖与节流
const debounce = (fn, delay) => {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, args), delay);
};
};
const throttle = (fn, limit) => {
let lastCall = 0;
return (...args) => {
const now = Date.now();
if (now - lastCall >= limit) {
fn.apply(this, args);
lastCall = now;
}
};
};
// 使用示例
window.addEventListener('resize', debounce(() => {
console.log('Window resized');
}, 200));
六、实用封装示例
1. 安全的 JSON 解析
const safeJsonParse = (str, defaultValue = null) => {
try {
return JSON.parse(str);
} catch (error) {
console.error('JSON parse error:', error);
return defaultValue;
}
};
// 使用示例
const data = safeJsonParse('{"a":1}'); // {a:1}
const invalid = safeJsonParse('invalid'); // null
2. 链式操作封装
class QueryBuilder {
constructor() {
this.query = {};
}
select(fields) {
this.query.select = fields;
return this;
}
where(conditions) {
this.query.where = conditions;
return this;
}
limit(num) {
this.query.limit = num;
return this;
}
build() {
return this.query;
}
}
// 使用示例
const query = new QueryBuilder()
.select(['name', 'age'])
.where({ age: { $gt: 18 } })
.limit(10)
.build();
最佳实践
- 单一职责原则:每个封装单元只做一件事
- 最小暴露原则:只暴露必要的接口
- 不可变性优先:尽量使用const和Object.freeze
- 文档化接口:使用JSDoc或TypeScript
- 错误处理:提供清晰的错误反馈
通过合理应用这些高级封装技术,可以显著提高代码的可维护性、可测试性和可扩展性。
文章来源于互联网:JavaScript 高级封装方法指南
目录 前言: 1.全局ID生成器 2.秒杀优惠券 2.1.秒杀优惠券的基本实现 2.2.超卖问题 2.3.解决超卖问题的方案 2.4.基于乐观锁来解决超卖问题 3.秒杀一人一单 3.1.秒杀一人一单的基本实现 3.2.单机模式下的线程安全问题 3.3.集群模式…
5bei.cn大模型教程网










