如何在JavaScript中实现函数的浅拷贝
如何在JavaScript中实现函数的浅拷贝
我来帮你搞定这个函数浅拷贝的需求~ 首先得明白为啥直接赋值func1 = func不行——这俩其实指向的是同一个函数对象,原函数的属性改了,func1的属性自然也跟着变。我们要的是一个新的函数对象,它和原函数执行逻辑一样,但自身属性是独立的,修改原函数的属性不会影响到它。
实现思路
函数在JS里本质也是对象,所以我们要做两件事:
- 创建一个新函数,让它的执行行为和原函数完全一致;
- 把原函数的所有自身属性(比如你例子里的
func.a)复制到这个新函数上。
基础实现代码
先给你一个最常用的版本,完全能满足你例子里的需求:
function copy(fn) { // 新函数执行时,调用原函数并传递this和参数,保证逻辑和原函数一致 const copiedFn = function(...args) { return fn.apply(this, args); }; // 把原函数的可枚举自身属性复制到新函数上 Object.assign(copiedFn, fn); return copiedFn; }
用你给的例子测试一下:
function func(x, y) { return [x,y] } func.a = 1; let func1 = func; let func2 = copy(func); func.a = 2; console.log(func1.a); // 输出 2,因为和原函数是同一个引用 console.log(func2.a); // 输出 1,完全符合预期!
进阶版:复制所有自身属性(包括不可枚举的)
如果原函数有不可枚举的自身属性,上面的Object.assign只会复制可枚举属性。要是需要保留所有自身属性,可以用下面的写法:
function copy(fn) { const copiedFn = function(...args) { return fn.apply(this, args); }; // 获取原函数的所有属性描述符,再批量定义到新函数上 const descriptors = Object.getOwnPropertyDescriptors(fn); Object.defineProperties(copiedFn, descriptors); return copiedFn; }
一些小提醒
- 这是浅拷贝:如果原函数的属性是引用类型(比如
func.data = { count: 0 }),修改原函数的func.data.count,拷贝后的函数的data.count也会跟着变——因为浅拷贝只复制了引用,这是浅拷贝的正常特性。 - 针对箭头函数:这个方法也适用!箭头函数的
this是词法绑定的,新函数调用时用apply传递this不会改变箭头函数的this,完全能保持原箭头函数的行为。
备注:内容来源于stack exchange,提问作者FaniX
相关产品推荐
相关产品推荐

