前几天一个面试中的问题,听到有点懵逼,因为从没听说过这种需求,这几天搜索了一通好像也没有明确的方案,自己能想到的是用 bind ? v 友有点子吗?
1
sherryqueen 2020-02-22 11:41:42 +08:00
拷贝一个函数?? 没了解过 占个座, 等楼下答复, 到时候来学习一下- -
|
2
yuankui 2020-02-22 11:48:19 +08:00
附楼问一下:如何序列化和反序列化一个函数?
|
3
qinfensky 2020-02-22 11:56:20 +08:00 via iPhone
函数的作用域不是独立的吗?除了个 ththis 指向的坑有时候需要 bind,拷贝的意义是什么?费解
|
4
lane1 2020-02-22 12:00:48 +08:00 1
|
5
afpro 2020-02-22 12:11:48 +08:00
为啥要 copy 一个函数 莫非 javascript 的函数是可变的?
|
6
rabbbit 2020-02-22 12:13:32 +08:00
https://stackoverflow.com/questions/1833588/javascript-clone-a-function
另外,怎么算函数? 普通函数 函数表达式 箭头函数 , typeof class 也返回 function 算不算函数? 很好奇什么情况下才会需要这种功能. |
7
dartabe 2020-02-22 12:25:25 +08:00
从函数式编程的角度来看 javascript 里面函数都尽量是纯函数 有一个就行了 其他地方都是他的引用啊
求大神解释 |
8
otakustay 2020-02-22 12:30:19 +08:00
不可能的,闭包是完全没办法克隆的
|
9
zckevin 2020-02-22 12:42:22 +08:00
1. hook javascript functions
2. utilize/modify VM internals |
10
ila 2020-02-22 12:42:33 +08:00 via Android
eval 吗
|
11
iMusic 2020-02-22 13:33:03 +08:00
笔记里的
``` function cloneFunction(func) { const bodyReg = /(?<={)(.|\n)+(?=})/m const paramReg = /(?<=\().+(?=\)\s+{)/ const funcString = func.toString() if (func.prototype) { const param = paramReg.exec(funcString) const body = bodyReg.exec(funcString) if (body) { if (param) { const paramArr = param[0].split(',') return new Function(...paramArr, body[0]) } else { return new Function(body[0]) } } else { return null } } else { return eval(funcString) } } ``` |
12
gaobing 2020-02-22 13:37:21 +08:00 via Android
ctrl c,ctrl v,深拷贝
|
13
fengbjhqs 2020-02-22 13:46:13 +08:00
感觉写一个深拷贝的函数会比较现实,
|
14
huanglexus 2020-02-22 13:49:20 +08:00
不知道楼主是不是听错了,如果是真的话,问这种问题的人很明显连基本的编程语言常识都不懂
|
15
Hilong 2020-02-22 13:57:51 +08:00 via Android
是不是如何实现深拷贝函数吧?
|
16
px920906 OP @huanglexus 我当时问了一句“深拷贝一个函数?”,说是的。。面试官水平应该没问题的,之前也问了许多正常的问题。不过后悔没追问他这种需求的场景
@fengbjhqs 我也是这么想的 @rabbbit 当时还真没想这么多 |
17
dartabe 2020-02-22 14:20:09 +08:00
看了一下 好像上面的 eval(func.toString)是可以的
|
18
rabbbit 2020-02-22 14:20:28 +08:00
面试者的原话说的是什么,直接问的如何深拷贝函数吗.
我猜可能是想问如何继承构造函数? |
19
leafdream 2020-02-22 14:28:11 +08:00
拷贝对象吧 拷贝个🔨的函数
|
20
tlday 2020-02-22 14:35:37 +08:00
TL;DR:考虑这种情况:
''' const inc = v => v+1; inc.vector = [1,2,3]; //或者用 Object.assign/Object.defineProperty inc.vector_add = function(num) { return this.vector.map(v => v + num) }; inc.t = 1; inc.t.a = 3; ''' 要求拷贝 inc 函数或者拷贝 inc.vector_add 函数。 正文: 个人理解首先应该问清楚是否同样拷贝 property。 因为函数式编程语言中,函数是一等公民,本质上是个 function 对象,又因为 js 里对象的特殊性(兼具其他语言 map/dict 的特性),所以问题实际上分化成两个问题,是否需要拷贝 property。 如果不需要拷贝 property,这个函数内部有可能引用自身的某个 property,需要考虑 js 里的 this 绑定问题。考虑 ES6 以后箭头函数和普通函数的 this 绑定问题(如何判断是普通函数还是箭头函数: https://stackoverflow.com/questions/28222228/javascript-es6-test-for-arrow-function-built-in-function-regular-function),无论是哪种函数,可靠的机制都是 apply 原 function 对象为 this。(这种情况需要考虑多次拷贝以后的调用栈深度,上面 StackOverflow 里的答案有人用双下划线开头的属性 hold 了一个最原始对象解决这个问题--评论有人指出 ES6 以后可以用 Symbol 而不是双下划线这种不太可靠的 trick ) 如果需要拷贝 property,那么相当于 js 里如何深拷贝一个(函数)对象 /map/dict,应该就是逐个遍历这个函数对象的属性,值引用类型的拷贝值,“引用”引用类型的同样作递归的深拷贝。同时考虑是否需要拷贝 property descriptor ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor )的问题(这里有个参考答案 https://github.com/lodash/lodash/issues/3043 )。面试的话,我觉得答到这里应该足够了,正常编程中感觉很少出现这种需求。 |
21
tlday 2020-02-22 14:39:19 +08:00
忽略代码最后两行,测试 js 时顺手写的
|
22
hyy1995 2020-02-22 15:59:10 +08:00
面试玩的是真的花啊
|
23
lipeiwei 2020-02-22 16:13:52 +08:00
吃个瓜,我觉得应该是听错了,应该是应该让你写深拷贝而已
|
24
lizz666 2020-02-22 16:15:43 +08:00
曾经也有过这样的疑惑,倒是在网上看到过以下这种改变 this 的方式,可能面试官认为这样就算深拷贝函数了吧
```js function test1() {} test1.a = 1 let test2 = test1.bind(null) test2.a // undefined ``` |
25
tonytonychopper 2020-02-22 17:35:42 +08:00 via Android
不了解,但是可以看下 lodash 是怎么实现的
|
26
7DLNU56W 2020-02-22 18:11:40 +08:00
利用 Function.prototype.bind 是不是可以实现呀~
|
27
tinyhill 2020-02-22 18:18:36 +08:00
应该是问深拷贝时的函数问题吧,比如 JSON.stringify/parse 会 gg
|
28
zhw2590582 2020-02-22 20:16:52 +08:00
要么考查 bind 构造一个新函数,要么考查从现有函数体提取字符串再构造一个新函数
|
29
mostkia 2020-02-23 09:22:23 +08:00
把函数当作字符串来处理不知道是不是可以,funciton 不带括号是不执行的,反而会打印出内容,利用 toString()方法接住打印出来的函转为字符串,然后就可以输出了,要转为 fun,外面包一个 eval 执行。
``` function uu(){ alert('???'); } var echo = uu.toString(); console.log(echo); eval(echo); ``` |
30
tairan2006 2020-02-23 20:59:49 +08:00
深拷贝一个函数?把代码复制一遍…
|
32
cj97 2021-01-22 09:50:37 +08:00
浅复制,深复制同理
``` const fn = () => 1; fn.a = 2; fn.f = () => 3; const obj = Object.assign({}, fn); const cloneFn = fn.bind(); Object.keys(obj).forEach(key => { cloneFn[key] = obj[key] }) ``` |
33
Tsuizen 2023-04-18 20:53:32 +08:00
new Function('return ' + fn.toString())();
|