JS 如何复制一个函数?

2021-12-08 12:52:02 +08:00
 aikilan
面试的时候面试官问如何复制数组、对象,我巴拉巴拉说,说完突然问我那如何复制一个函数呢?


我瞬间闷逼了,能想到的原型链上下手,但是似乎也不是什么好的解法,面试官提示说你能想到的返回函数的 API 有啥,我就更闷逼了。

迷惑人的一天。
2517 次点击
所在节点    程序员
30 条回复
amber0317
2021-12-08 13:08:17 +08:00
f.bind(null)
noe132
2021-12-08 13:17:41 +08:00
复制不了的。我给你个引用了闭包的函数,你能复制一样的东西吗?
DrakeXiang
2021-12-08 13:25:36 +08:00
函数也是对象啊,不过他的提示可能就是 bind/call/apply 这种吧
Mutoo
2021-12-08 13:27:36 +08:00
思路:function.toString() 可以拿到函数的字面量,然后用正则解析出参数和函数 body ,调用 new Function() 就可以复制函数了。当然这种方式只能复制一些纯函数,对闭包或者其它有 Side Effect 的函数不灵。

fn_a = function(x,y){return x+y;};
fn_a.toString()
> "function(x,y){return x+y;}"

fn_b = (x, y) => x+y;
fn_b.toString()
> (x, y)=>x+y;
robinlovemaggie
2021-12-08 13:28:50 +08:00
=> 算不算?
maichael
2021-12-08 13:29:22 +08:00
同楼上,bind 、apply 。
vision1900
2021-12-08 13:45:23 +08:00
vision1900
2021-12-08 13:50:03 +08:00
@vision1900 但我感觉如果用 bind 不设置 this 的话,好像没有任何实际意义
waiaan
2021-12-08 14:05:48 +08:00
不是直接赋值给一个变量就行了?复制函数是什么意思?
bzw875
2021-12-08 14:09:27 +08:00
面试官问的不好
misdake
2021-12-08 14:11:58 +08:00
b = a.bind(null) 和 b = a 相比,除了判断相等的结果不一样之外还有别的区别吗
vanton
2021-12-08 14:13:26 +08:00
嗯?

为啥那么复杂,很简单的处理下就好了。

```
/** 原始函数 */
function f1() {
var n = 999;

nAdd = function () {
n += 1;
};

function f2() {
alert(n);
}

return f2;
}

/** 复制?? */
function a(x) {
return x;
}


/** 复制原始函数到 f3 */
var f3 = a(f1);

console.log(f3);

f3();

```
secondwtq
2021-12-08 14:13:37 +08:00
函数不需要复制啊,一个东西需要区分“复制”和“引用”,是因为这东西可以修改,或者需要管理内存。函数没法修改,内存管理 JS 帮你干了,就不需要复制了。
jtwor
2021-12-08 14:14:42 +08:00
感觉是想问深拷贝与浅拷贝,js 所有都是对象,能复制的。。
Kasumi20
2021-12-08 14:15:03 +08:00
函数的本质就是提高可复用性,降低代码复杂度,你复制函数有什么意义?
Geo200
2021-12-08 14:16:15 +08:00
为什么面试要问那么奇怪的问题?真实的业务场景里真的会用到吗
Kasumi20
2021-12-08 14:17:13 +08:00
我能想到的唯一的用途是对类的成员函数进行 Hook
GuuJiang
2021-12-08 14:17:36 +08:00
ctrl+c/ctrl+v (狗头

能问出这种问题,要么是你曲解了面试官的意思,要么面试官是个煞笔
violetlai
2021-12-08 14:18:18 +08:00
问的太笼统太不严谨了, 你能想到 n 种环境下 n 种解法。

但是面试官只会假定一种环境 ,不给你设定前提,那就是面试官的问题了。

就像问你 css 盒子水平居中有几种方法,但是不给你说是否有父级,父级宽高是不是固定等等假定的条件,你总不可能每种都给他写出来吧
jones2000
2021-12-08 14:31:14 +08:00
直接编译这个函数, 生成这个函数的 AST (抽象语法树),这个就可以了。 如果要执行这个函数, 直接执行这个 AST 就可以了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/820839

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX