应使用类实例化、Object.assign或工厂函数创建独立新实例,而非浅拷贝;类方式最推荐,可隔离状态并正确绑定方法,静态成员需单独处理。

直接复制工具类对象不能只用浅拷贝,因为方法是函数引用,而多数工具类依赖 this 或闭包状态。关键不是“复制对象”,而是“获得一个功能等价、独立可用的新实例或新命名空间”。
用类(class)封装,实例化新对象
如果原工具类是用 class 定义的(推荐方式),最自然的做法是创建新实例:
class Utils {
static version = '1.0';
constructor(prefix = '') {
this.prefix = prefix;
}
log(msg) { console.log(this.prefix + msg); }
format(str) { return str.toUpperCase(); }
}
// 复制:新建一个独立实例(可带不同配置)
const utilsA = new Utils('[A]');
const utilsB = new Utils('[B]'); // 行为一致,状态隔离
✅ 优点:方法绑定正确,实例属性互不干扰;❌ 注意:静态成员(如 Utils.version)不会被实例继承,需单独处理。
用 Object.create + Object.assign 模拟“原型级复制”
若工具类是纯静态方法的对象(如 const MyUtils = { foo() {}, bar() {} }),可安全浅拷贝其方法引用:
立即学习“Java免费学习笔记(深入)”;
- 方法本身是不可变的函数值,复制引用无副作用
- 用
Object.assign({}, MyUtils)或展开语法{...MyUtils}即可 - 若含嵌套对象或需要深隔离(比如内部缓存),再对特定字段深拷贝
const OriginalUtils = {
cache: new Map(),
add(x, y) { return x + y; },
getConfig() { return { env: 'prod' }; }
};
// 基础复制(方法引用共享,安全;普通属性也复制)
const CopyUtils = { ...OriginalUtils };
// 如需隔离 cache,单独重置
CopyUtils.cache = new Map();
用工厂函数返回新作用域对象
适合需要私有状态或闭包环境的工具集:
function createUtils(options = {}) {
const { prefix = '', debug = false } = options;
return {
log(msg) { console[debug ? 'info' : 'log'](prefix + msg); },
retry(fn, times = 3) {
let lastErr;
for (let i = 0; i < times; i++) {
try { return fn(); }
catch (e) { lastErr = e; }
}
throw lastErr;
}
};
}
const utils1 = createUtils({ prefix: '[API]', debug: true });
const utils2 = createUtils({ prefix: '[DB]' }); // 完全独立
✅ 状态和行为都彻底隔离;✅ 无需 class 语法,兼容性好;✅ 易测试、易配置。
避免踩坑:这些“复制”方式不推荐
- JSON.stringify + JSON.parse:会丢弃所有方法、undefined、Symbol、Date、RegExp 等
- structuredClone:虽支持函数(Chrome 98+ 实验性),但跨浏览器不稳,且仍无法克隆闭包变量
-
for…in + call/apply 逐个绑定:容易漏掉不可枚举属性、Symbol 键,
this绑定易出错


















